Menedżer aktualizacji

Menedżer aktualizacji przeprowadza aktualizacje maszyny wirtualnej. Menedżer aktualizacji współpracuje z klientem, który jest dostarczany przez integratora systemów. Klient udostępnia ładunek aktualizacji i koordynuje ogólną aktualizację pojazdu. Aktualizacja składa się z tych kroków:

  1. GOTOWY: nie trwa żadna aktualizacja.
  2. PRZYGOTOWANIE: Menedżer aktualizacji zapisuje aktualizację na dysku, ale jej nie aktywuje.
  3. AKTYWACJA: Menedżer aktualizacji aktywuje przygotowaną aktualizację, aby zaczęła działać po ponownym uruchomieniu.
  4. ZATWIERDZENIE: Menedżer aktualizacji sprawia, że aktualizacja jest trwała.

Uproszczony automat stanów ilustrujący przepływ pracy Menedżera aktualizacji

Rysunek 1. Ogólne działanie Menedżera aktualizacji.

Menedżer aktualizacji obsługuje aktualizacje systemu i aktualizacje pakietów usług, które są opisane na tej stronie.

Aktualizacje systemu

System operacyjny Android używa 2 zestawów partycji nazywanych slotami, z których tylko jeden slot jest aktywny naraz. Aktualizacja systemu zapisuje nowy zestaw partycji w nieaktywnym slocie, a system przełącza aktywny slot przy następnym ponownym uruchomieniu. Więcej informacji o tworzeniu aktualizacji systemu znajdziesz w artykule Aktualizacje systemu A/B.

Aktualizacje pakietów usług

W AAOS SDV pakiety usług łączą usługi w APEX-ach. Aktualizacje pakietów usług przygotowują nowe pliki APEX w sesjach tymczasowych. System aktywuje te zaktualizowane pakiety po ponownym uruchomieniu systemu. Więcej informacji o tworzeniu APEX-ów pakietów usług znajdziesz w artykule Aktualizacje pakietów usług.

Automat stanów

Automat stanów Menedżera aktualizacji jest sterowany przez żądania od klienta i zdarzenia z usług systemowych. Menedżer aktualizacji został zaprojektowany tak, aby był odporny na awarie. Może przywrócić swój stan i wznowić proces aktualizacji nawet po nieoczekiwanych ponownych uruchomieniach lub awariach.

Automat stanowy ilustrujący przepływ pracy Menedżera aktualizacji

Rysunek 2. Automat stanów Menedżera aktualizacji.

Interfejs API

Menedżer aktualizacji udostępnia interfejs API, który steruje procesem aktualizacji za pomocą automatu stanów. Interfejs API używa VSIDL, który obsługuje klientów znajdujących się na dowolnej maszynie wirtualnej obsługującej SDV Comms i wysyła powiadomienia o nieudanych żądaniach.

Zabezpieczenia i dostęp

System ogranicza dostęp do interfejsu API za pomocą zasad autoryzacji. Tylko autoryzowany klient może wywoływać Menedżera aktualizacji.

Aktualności

Operacje aktualizacji mogą trwać długo, dlatego Menedżer aktualizacji udostępnia asynchroniczne aktualizacje stanu. Klienci muszą monitorować stan, subskrybując aktualizacje stanu.

Zarządzanie subskrypcjami

  • Subskrybowanie: klienci subskrybują aktualizacje stanu, wywołując metodę SubscribeToStatusUpdates():

    rpc SubscribeToStatusUpdates(SubscribeToStatusUpdatesRequest)
        returns (SubscribeToStatusUpdatesResponse) {}
    
    message SubscribeToStatusUpdatesRequest {}
    
    message SubscribeToStatusUpdatesResponse {}
    

    Zanim klient wywoła metodę SubscribeToStatusUpdates(), musi uruchomić interfejs RPC , który implementuje UpdateManagerListenerService.

  • Anulowanie subskrypcji: klienci mogą przestać otrzymywać aktualizacje stanu, wywołując metodę UnsubscribeFromStatusUpdates():

    rpc UnsubscribeFromStatusUpdates(UnsubscribeFromStatusUpdatesRequest)
        returns (UnsubscribeFromStatusUpdatesResponse) {}
    
    message UnsubscribeFromStatusUpdatesRequest {}
    
    message UnsubscribeFromStatusUpdatesResponse {}
    

UpdateManagerListenerService

Klienci, którzy wywołują metodę SubscribeToStatusUpdates() w usłudze UpdateManagerService, muszą zaimplementować tę usługę, aby otrzymywać aktualizacje stanu:

service UpdateManagerListenerService {
  /* Called when there is a status update from the Update Manager. */
  rpc OnStatusUpdate(OnStatusUpdateRequest) returns (OnStatusUpdateResponse) {}
}

message OnStatusUpdateRequest {
  oneof status_update {
    UpdateManagerStatus update_manager_status = 1;
    UpdateProgress update_progress = 2;
  }
}

message OnStatusUpdateResponse {}

Metoda OnStatusUpdateRequest dostarcza jeden z 2 możliwych komunikatów za pomocą pola status_update:

  1. UpdateManagerStatus: wysyłany, gdy zmienia się stan Menedżera aktualizacji.
  2. UpdateProgress: wysyłany, aby wskazać postęp aktualizacji w stanach PREPARE i ACTIVATE_PRE_REBOOT, ponieważ proces może zająć dużo czasu.

Stan i komunikaty o błędach

Komunikaty o stanie zawierają szczegółowe informacje o stanie i wszelkich błędach:

  • UpdateManagerStatus: informuje o bieżącej fazie aktualizacji i przyczynie niepowodzenia:

    message UpdateManagerStatus {
      /* The current state of the update */
      UpdateState update_state = 1;
      /* The reason for the failure, if the update failed */
      FailureReason failure_reason = 2;
    }
    
    enum UpdateState {
      /* The Update Manager is ready to accept a new update. */
      READY = 0;
      /* An update is being prepared. */
      PREPARE = 1;
      /* The update failed during the prepare step. Roll back the update to start a
       *   new update. */
      PREPARE_FAILURE = 2;
      /* The update was prepared successfully. */
      PREPARE_COMPLETE = 3;
      /* A rollback has started from the prepare step. When complete, transitions
       *   to READY. */
      PREPARE_ROLLBACK = 4;
      /* The prepared update is being activated. */
      ACTIVATE_PRE_REBOOT = 5;
      /* The update failed during the activate step before the reboot. Roll back the
       *   update to start a new update. */
      ACTIVATE_PRE_REBOOT_FAILURE = 6;
      /* The update was activated successfully. Reboot to complete activation. */
      ACTIVATE_PRE_REBOOT_COMPLETE = 7;
      /* A rollback has started from the activate pre-reboot step. When complete,
       *   transitions to READY. */
      ACTIVATE_PRE_REBOOT_ROLLBACK = 8;
      /* An update was successfully activated after the reboot. The update needs to
       *   be committed or rolled back to be completed. */
      ACTIVATE_POST_REBOOT_COMPLETE = 9;
      /* A rollback has started from the activate post-reboot step. */
      ACTIVATE_POST_REBOOT_ROLLBACK = 10;
      /* The rollback was completed successfully. Reboot to complete the
       *   rollback. */
      ACTIVATE_POST_REBOOT_ROLLBACK_COMPLETE = 11;
      /* The update is being committed. When complete, transitions to READY */
      COMMIT = 12;
      /* The prepare request is being cancelled */
      PREPARE_CANCEL = 13;
      /* The system update has started suspending */
      PREPARE_SUSPEND = 14;
      /* The system update has finished suspending */
      PREPARE_SUSPEND_COMPLETE = 15;
    }
    
    message FailureReason {
      /* The original error that triggered the failure */
      ErrorCode error_code = 1;
      /* Binder error message for most ErrorCodes. */
      string error_message = 2;
    }
    
    enum ErrorCode {
      Unspecified = 0;
      /* Error from UpdateEngine service */
      UpdateEngineError = 1;
      // Error from the ApexService
      ApexServiceError = 2;
      // Error from the BootControlService
      BootControlServiceError = 3;
      // Error from the VoldService
      VoldServiceError = 4;
    }
    
  • UpdateProgress: informuje o bieżącym stanie z Update Engine podczas aktualizacji systemu:

    message UpdateProgress {
      /* Matches the enum UpdateStatus from the UpdateEngine service. */
      int32 status_code = 1;
    
      /* A value ranging from 0.0 to 1.0, 1.0 representing the process is complete. */
      float percentage = 2;
    }
    
    

Natychmiastowe pobieranie stanu

Aktualny stan i ładunek możesz pobrać w dowolnym momencie, wywołując metodę GetStatus(). Komunikaty SystemUpdatePayload i ServiceBundleUpdatePayload są opisane w sekcji Przygotowanie.

rpc GetStatus(GetStatusRequest) returns (GetStatusResponse) {}

message GetStatusRequest {}

message GetStatusResponse {
  /* The status of the Update Manager */
  UpdateManagerStatus update_manager_status = 1;
  /* The current update payload, if one has been set through the Prepare() request */
  oneof payload {
    SystemUpdatePayload system_update_payload = 2;
    ServiceBundleUpdatePayload service_bundle_update_payload = 3;
  }
}

Przygotowanie

Żądanie Prepare rozpoczyna proces aktualizacji przez przygotowanie ładunku, ale system czeka na aktywowanie aktualizacji:

rpc Prepare(PrepareRequest) returns (PrepareResponse) {}

message PrepareRequest {
  oneof payload {
    SystemUpdatePayload system_update_payload = 1;
    ServiceBundleUpdatePayload service_bundle_update_payload = 2;
  }
}

message PrepareResponse {}

Jeśli żądanie jest prawidłowe, stan przechodzi w stan PREPARE, a Menedżer aktualizacji rozpoczyna aktualizację.

Typ ładunku określa typ aktualizacji.

Ładunek aktualizacji systemu

Aktualizacja systemu używa danych SystemUpdatePayload, które wymagają ścieżki do obrazu aktualizacji OTA. Pozostałe parametry są analizowane z obrazu, ale możesz je określić, aby zastąpić przeanalizowane wartości.

message SystemUpdatePayload {
  /* Absolute path to the update image (e.g., /updates/ota_update.zip) */
  string payload = 1;

  /* Offset (in bytes) into the payload where the payload binary starts. */
  optional int64 payload_offset = 2;

  /* The amount of data (in bytes) to read from "payload" as the update payload. */
  optional int64 payload_size = 3;

  /* The header key value pairs to apply with the payload. */
  map<string, string> header_key_value_pairs = 4;
}

Menedżer aktualizacji przetwarza obraz OTA (dostarczony przez klienta w katalogu /data/ota_package), aby wykonać kroki po instalacji, ale nie przełącza aktywnego slotu rozruchowego. Następnie przechodzi do stanu PREPARE_COMPLETE w przypadku powodzenia lub do stanu PREPARE_FAILURE w przypadku niepowodzenia.

Wstrzymanie aktualizacji systemu

Proces aktualizacji możesz wstrzymać tylko w przypadku aktualizacji systemu. To żądanie jest prawidłowe tylko w stanie PREPARE.

  • Wstrzymaj: wstrzymuje aktualizację, przechodząc do stanu PREPARE_SUSPEND.

    rpc Suspend(SuspendRequest) returns (SuspendResponse) {}
    
    message SuspendRequest {}
    
    message SuspendResponse {}
    

    W przypadku powodzenia stan przechodzi w stan PREPARE_SUSPEND_COMPLETE. W przypadku niepowodzenia stan przechodzi w stan PREPARE_FAILURE.

  • Wznów: kontynuuje wstrzymaną aktualizację. Jest to prawidłowe tylko w stanie PREPARE_SUSPEND_COMPLETE.

    rpc Resume(ResumeRequest) returns (ResumeResponse) {}
    
    message ResumeRequest {}
    
    message ResumeResponse {}
    

    Stan wraca do stanu PREPARE.

Ładunek aktualizacji pakietu usług

Aktualizacja pakietu usług używa ServiceBundleUpdatePayload, który zawiera ścieżki do plików APEX i ustawia limit prób aktywacji.

message ServiceBundleUpdatePayload {
  /* Absolute path to an .apex file. Multiple .apex files can be included. */
  repeated string apex_path = 1;

  /* Number of boots to attempt activation before aborting. Must be > 0. */
  int32 boot_attempts = 2;
}

Menedżer aktualizacji sprawdza, czy pliki APEX są prawidłowo podpisane, i przygotowuje je w sesji. W przypadku powodzenia stan przechodzi w stan PREPARE_COMPLETE. W przypadku niepowodzenia stan przechodzi w stan PREPARE_FAILURE.

Aktywuj

Żądanie Activate aktywuje przygotowaną aktualizację przy następnym ponownym uruchomieniu.

rpc Activate(ActivateRequest) returns (ActivateResponse) {}

message ActivateRequest {}

message ActivateResponse {}

Przed ponownym uruchomieniem

Podczas aktywowania aktualizacji Menedżer aktualizacji przechodzi do stanu ACTIVATE_PRE_REBOOT. Menedżer aktualizacji tworzy też punkt kontrolny danych użytkownika który zacznie obowiązywać po ponownym uruchomieniu systemu.

Działania aktywacyjne różnią się w zależności od typu aktualizacji:

  • Aktualizacja systemu: system wykonuje kroki po instalacji i ustawia slot rozruchowy, który ma zostać przełączony przy następnym ponownym uruchomieniu.
  • Aktualizacja pakietu usług: system oznacza przygotowaną sesję APEX jako gotową do aktywacji.

Jeśli system pomyślnie aktywuje aktualizację, stan przechodzi w stan ACTIVATE_PRE_REBOOT_COMPLETE, co oznacza, że maszyna wirtualna jest gotowa do ponownego uruchomienia. W przeciwnym razie stan przechodzi w stan ACTIVATE_PRE_REBOOT_FAILURE.

Po zrestartowaniu

Po ponownym uruchomieniu system uruchamia się w trybie punktu kontrolnego. W tym trybie system nie zapisuje żadnych zmian w partycji danych użytkownika w pamięci trwałej. Jeśli system nie zatwierdzi aktualizacji, przywróci te zmiany do stanu początkowego.

Limit uruchamiania

System przywraca zmiany w partycji danych użytkownika w jednym z tych przypadków:

  • Klient wysyła wyraźne żądanie Rollback() i ponownie uruchamia system.
  • System uruchamia się zbyt wiele razy bez wywołania przez klienta metody Commit() lub Rollback(). Limit uruchamiania różni się w zależności od typu aktualizacji:
    • Aktualizacja systemu: ustawia go implementacja BootControl. Domyślny limit w implementacji używanej przez urządzenia Cuttlefish to na przykład 7 uruchomień.
    • Aktualizacja pakietu usług: ustawia go pole boot_attempts w ServiceBundleUpdatePayload dostarczonym przez klienta, gdy wysyłane jest żądanie Prepare().
Weryfikacja

Następnie system weryfikuje aktualizację:

  • Aktualizacja systemu: dm-verity sprawdza, czy zaktualizowany slot nie jest uszkodzony.
  • Aktualizacja pakietu usług: apexd sprawdza podpis każdego APEX-a i montuje obraz APEX-a w systemie plików.

Jeśli weryfikacja się powiedzie, stan przechodzi w stan ACTIVATE_POST_REBOOT_COMPLETE. Menedżer aktualizacji czeka na wywołanie metody Commit() lub Rollback().

Jeśli weryfikacja się nie powiedzie, system uruchomi się ponownie. Gdy system osiągnie limit uruchamiania, przywróci stan pierwotny:

  • Aktualizacja systemu: system przywraca pierwotny slot.
  • Aktualizacja pakietu usług: zaktualizowane APEX-y są usuwane, a pierwotne APEX-y są ponownie aktywowane.

Jeśli weryfikacja nie powiedzie się w przypadku dowolnego typu aktualizacji, po przywróceniu stanu pierwotnego stan przechodzi w stan ACTIVATE_PRE_REBOOT_FAILURE.

Przywróć

Żądanie Rollback rozpoczyna przywracanie systemu do stanu sprzed aktualizacji.

rpc Rollback(RollbackRequest) returns (RollbackResponse) {}

message RollbackRequest {}

message RollbackResponse {}

Żądanie Rollback() możesz wysłać w wielu stanach. W zależności od stanu początkowego system podejmuje różne działania i przechodzi do różnych stanów:

Stan, w którym wydano polecenie przywrócenia Przejście stanu Działanie systemu
(Tylko aktualizacja systemu) PREPARE, PREPARE_SUSPEND_COMPLETE &rightarrow; PREPARE_CANCEL &rightarrow; PREPARE_ROLLBACK &rightarrow; READY Aktualizacja systemu: anuluje aktualizację systemu.
PREPARE_FAILURE, PREPARE_COMPLETE &rightarrow; PREPARE_ROLLBACK &rightarrow; READY Aktualizacja systemu: anuluje aktualizację systemu.

Aktualizacja pakietu usług: przerywa przygotowaną sesję APEX.
ACTIVATE_PRE_REBOOT_COMPLETE, ACTIVATE_PRE_REBOOT_FAILURE &rightarrow; ACTIVATE_PRE_REBOOT_ROLLBACK &rightarrow; READY Wyłącza punkt kontrolny danych użytkownika.

Aktualizacja systemu: anuluje przełączenie slotu rozruchowego.

Aktualizacja pakietu usług: usuwa przygotowany APEX.
ACTIVATE_POST_REBOOT_COMPLETE &rightarrow; ACTIVATE_POST_REBOOT_ROLLBACK &rightarrow; ACTIVATE_POST_REBOOT_ROLLBACK_COMPLETE Wyłącza punkt kontrolny danych użytkownika.

Aktualizacja systemu: przełącza slot rozruchowy z powrotem.

Aktualizacja pakietu usług: przywraca aktywne sesje APEX.

Aby przywrócenie zostało zastosowane, wymagane jest ostateczne ponowne uruchomienie. Po nim stan przechodzi w stan READY.

Zatwierdzenie

To żądanie wskazuje, że aktualizacja została zakończona, i trwale stosuje wszystkie zmiany.

rpc Commit(CommitRequest) returns (CommitResponse) {}

message CommitRequest {}

message CommitResponse {}

Podczas wykonywania działań zatwierdzających stan przechodzi w stan COMMIT:

  • Aktualizacja systemu: Menedżer aktualizacji oznacza uruchomienie jako udane, co uniemożliwia przyszłe przywrócenie i wybiera ten slot podczas kolejnych uruchomień.
  • Aktualizacja pakietu usług: Menedżer aktualizacji oznacza przygotowaną sesję APEX jako udaną, zamykając sesję aktualizacji i trwale aktywując pakiety.

Gdy system zatwierdzi aktualizację, Menedżer aktualizacji zatwierdzi punkt kontrolny danych użytkownika. System zapisuje wszystkie nowe dane użytkownika zapisane podczas tego uruchomienia w pamięci trwałej. Menedżer aktualizacji wraca do stanu READY, co oznacza, że aktualizacja została zakończona.

Odinstalowywanie APEX-ów

Żądanie UninstallApex usuwa wersję pakietów usług w katalogu /data. Metodę UninstallApex możesz wywołać w dowolnym stanie, ale aby odinstalowanie zostało zastosowane, konieczne jest ponowne uruchomienie maszyny wirtualnej. Dlatego unikaj wywoływania metody UninstallApex podczas aktualizacji. Metoda UninstallApex nie usuwa preinstalowanych APEX-ów, nie czyści danych APEX-ów ani nie usuwa nieaktywnych wersji APEX-ów.

rpc UninstallApex(UninstallApexRequest) returns (UninstallApexResponse) {}

message UninstallApexRequest {
  message ApexInfo {
    string module_name = 1;
    int64 version_code = 2;
  }
  repeated ApexInfo apexes = 1;
}

message UninstallApexResponse {}