2013年5月16日 星期四

[windows]程式更新機制自動化的考量(3)-各角色工作描述

在 google 的 Omaha 中,主要分成三個部份,也就是三個角色,這三個角色在整個流程的工作大致已經描述過(前文一前文二)。接下來,則是再詳細說明,各個角色的工作項目的內容。

Client

Omaha client 是 windows 應用程式,經由客製化的 windows 安裝程式 安裝至 windows 環境中。Omaha client 有以下的功能:

  • 在所在的主機上,安裝及更新 google 應用程式。
  • 定期與 update server 交談,決定是否有需要做更新。
  • 提供簡單的進度條畫面,可通知使用者,「 omaha client 的初始安裝」已經發生。
  • omaha client 具有提升權限的功能。就算應用程式執行在低權限的等級時,依然可以讓應用程式更新自己。
  • 提供一個程式當機回報機制,讓應用程式使用。

client 可以平行處理多個下載,多個循序的安裝,也可以續傳或重新下載檔案。

client 不是一個獨立的應用程式,所以它不能單獨被移除。它應視為是應用程式的一部份,當最後一個 google 應用程式被移除時,它會自行移除。

為了要回報安裝及更新的報告,omaha 包含了一個通用的程式當機報告的機制給 google 應用程式使用。其中使用了 Breakpad 專案的 network library,而 client,會處理 local minidump 的儲存,報告的佇列動作。

Omaha client 由兩大部份組成:

  • Runtime,處理所有的更新及安裝 service。
  • Web browser control (Active X for IE,NPAPI for others),這允許 google 網頁及 google 應用程式可以要求 runtime 做一些事情。

Client Runtime

Client runtime 擁有下列的功能:

  • 自動啟動,如此才能為所有的應用程式服務。
  • 依需求,提升權限,以執行安裝及自動更新。
  • 自動更新的輪詢(polling)。
  • 從 google download server 下載安裝檔。
  • 執行 google 安裝檔。
  • 一個持久的工作佇列,以達成平行處理可重開始的下載工作及安裝工作。
  • 進度條及狀態畫面的掛勾(hook),UI 程式可以從這知道狀況。
  • 自我解安裝,當最後一個註冊的應用程式被解安裝的時候。
  • 報告安裝成功或失敗。
  • 使用狀況收集
  • google 應用程式的當機報告的回報機制。
  • 認證及驗證安裝檔。

 

執行模型

Runtime 的功能,被分成數個行程 (process)。最明顯的是核心行程及許多的工作者行程 (worker process)。設計成如此有一些理由:強固性、以最小權限執行、儘量以登入者的身份執行 google 安裝檔、避免長生命行程的資源消耗或佔用。

Runtime 核心的執行模型有兩種,端看 Omaha 是如何被安裝的。

  1. Omaha 安裝給整台電腦。這需要使用者有管理者權限。在這個情況下,有一個 Windows service 是使用 SYSTEM 身份執行。它會分配許多工作給工作者行程。在更新整機安裝的應用程式(per-machine applications)時,工作者行程也是用 SYSTEM 身份執行。當工作都結束時,工作者行程會自己關閉。
  2. Omaha 只安裝給現在使用者。這個情況就不會有 service 安裝其中,也沒有更新整機安裝應用程式的時機。所以執行模型只有 goopdate 工作者行程,會在登入使用者的 interactive session 中。

在不同的作業系統(Windows 2000, XP, and Vista)執行的行為要一樣,這一點的要求是非常重要的。同時,核心行程在「整機安裝」、「使用者安裝」的執行模型也幾乎一樣。在大部份情況中,整機安裝與使用者安裝的安裝資訊是隔離的。

有一種情況,Omaha 為了整機安裝,使用 local system 身份執行了一個核心行程,為了使用者安裝,也使用目前登入使用者的身份執行一個核心行程。這種狀況就會執行兩個核心行程。這裡可以有個增加效律的作法,就是以local system 身份執行一個核心行程,然後以需求啟動使用者身份的核心行程。

整機安裝的 Omaha 核心行程,在開機時,以系統服務(system service)呼叫的方式啟動。不把 Omaha 本身作成 service 的理由是:在 Windows XP 有個 bug,如果這 service crash,會讓這個 service 無法更新。在使用者安裝模式,核心行程是用登入使用者的 shell 執行的。這避免了單點失敗,在核心行程沒有執行的情況下(不管任何理由),我們另外使用 Windows system scheduler 來啟動核心行程。我們期望 Omaha 的 available 的時間就跟 Windows OS 的 uptime 一樣長。

Omaha 核心要非常可靠及輕量:

  • 做越少事越好,而且保證做到:安裝工作者行程,完成無聲更新、權限提升,支援 breakpad crashes。
  • 移除對某些 Windows 模組的依頼:不要 msxml,不要 shell,不要 network,不要 UI,不要 crypto,不要 wintrust 等等。
  • 降低資源的消耗
  • 較少的程式碼,且儘量使用 OS 層底層的程式,只求穩固、穩固、穩固。

Omaha 工作者行程則是做大部份的工作:

  • 統一的 IPC 溝通機制是必要的。
  • 工作者行程之間的溝通與同步,保持在最低限度。因為 isolation 與 share-nothing 是設計的概念。
  • 工作者行程,使用新的網路堆疊及新的 CUP ( client update protocol, which uses HMACs over plain HTTP instead of HTTPS)
  • To facilitate firewall traversals, a constant shell is used

 

應用程式註冊

為了讓應用程式收到更新,應用程式必須要在 Omaha 註冊。應用程式註冊機制建立在 windows registry。Omaha 有兩個主要的更新規範,這會影響 Omaha 如何得知應用程式的註冊。

  1. 整機更新 (per-machine updates)
  2. 使用者更新 (per-user udpates)

在整機更新的情況,每一個整機安裝的應用程式會建立一個 key HKLM/Software/Google/Update/Clients/{GUID}。在這個 key 底下,應用程式建立下列的值:

  • pv (現在產品版本,例 1.0.20.0)
  • name (這個值忽略,但 debug 時很好用)

在使用者更新的情況,key 所在的位置是 HKCU/Software/Google/Update/Clients/{GUID}。其他與整機更新相同。

當更新動作開始,Omaha 使用 SYSTEM 身份執行整機更新,使用登入的使用者執行使用者更新。這是假設使用者有一個 active session。也就是說,當使用者沒登入時,使用者更新是不執行的。只要,那些 key 底下有任何東西,Omaha 會不停偵測是否有更新,並執行應用程式的更新。有可能發生一個狀況,應用程式當掉且應用程式的 Omaha 註冊是啟用的,例如,使用者剛殺掉應用程式檔案。 不幸的是,Omaha 不會知道這種情況的發生,它仍會下載程式,執行更新,直到應用程式的註冊被清除。

把註冊的 key 及底層實作細節讓應用程式知道是有缺點的。這會破壞 Omaha 的封裝。有討論認為,目前這種實作細節從應用程式連結的 code library 抽離出來會比較好。然而,現在的註冊機制有個很大的好處,註冊 key 可以容易地從應用程式的安裝腳本(任何現有的 installer 的技術)產生,於是與 Omaha 整合變得容易。

自動啟動

整機安裝時的 Omaha service,是設定成自動執行的。如果 service 當機,會使用 SCM failover 機制重啟 service。當 Omaha 是使用者安裝的方式安裝,goopdate 工作者行程會由 windows shell 從HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run 啟動。

排程器

client runtime 要定時執行一些工作,像是發出更新檢查要求給伺服器,確認是否有更新。這工作是分配給排程器。排程器的程式是在 Omaha 核心行程中。排程器的需求是一段時間執行一個工作者行程。

很多建議我們使用 windows 內建的排程器而不要用自己寫的。windows vista 的排程器有很大的改良。但在 XP 及 windows 2003 有一些限制:

  1. 在排程器有個認證上的問題。因為排程器的使用者認證是使用 cache 的認證。如果使用者後來改密碼,排程器之後會認為認證失敗。這在 vista 有修正。
  2. 在 2003 的任務排程器只能允許 administrators 使用。
  3. 如果機器在 sleep state,有些硬體上的任務就不會排入。有些排入的任務會在某些情況下失敗,因為 suspected ACPI interactions。其中一個極端的情況是網路線被拔掉時,機器不會做排程。

資源與時機的條件

runtime 在考量資源消耗及更新時機,有一些條件。

在資源限制上:

  • 確保不會用光使用者的硬碟空間
  • 使用少量的記憶體,延遲載入不需要的模組。(This is very important for resident core)
  • 如果沒有網路連線,就不要執行自動更新(避免撥接用戶自動撥號)
  • 限制背景下載的頻寬
  • 嘗試當使用者機器在 idle 時,更新應用程式

在更新時機上:

  • 至少一天一次的更新檢查
  • 循序的下載及安裝

 

Web Browser Control

Web Browser Control 提供介面給 google web page 及 client application,給予 one-click 網頁安裝及 rich update client as Pack 的特色。這需要限制存取,所以只有認證的 google 網頁及應用程式能存取 client runtime 提供的 service。The interface is defined by very coarse-granularity functions。不使用 "download file X from server Y" 這種方式,而是使用 "download application id X from Google" 這種方式。當 client 有安全漏洞時,這種 interface 的限制可降低傷害。

Crash Reporting

有兩個主要的部份是 crash reporting 在 windows 上要做的,產生 minidump 及回報給伺服器。每個應用程式仍然需要負責捕捉例外及通知 Omaha,以產生及傳送 minidump 給 google 伺服器。minidump 是放在一個安全的目錄,是 Omaha 可以寫入的地方。Omaha 有程式試著降低意外的「自我-阻斷攻擊」(self-DDoS),防範在回報重要資料時過於頻繁的當機,或許是發現重覆的 minidump 產生或一定次數的當機的報告產生時就不回報。

Meta-Installer

The Omaha meta-installer 是一個簡單的 wrapper,包含了 client 及安裝一個或數個 google 應用程式的資訊。它擁有以下的功能:

  • 安裝 client,如果本來沒有安裝
  • 更新 client,如果有更新的 client。
  • 啟動 client,如果本來有安裝,但沒有啟動。
  • 佇列應用程式的安裝要求到 client。

我們的目標是最小化安裝程式,小於 172KB (在現今最慢的 modem  的速度 28.8kbps 的 10 wire bits per data bits,在一分鐘內可下載完畢)。目前的 meta-installer 超過這個大小。我們仍在尋找降低檔案大小的方法。

Server

The google update server 不是 omaha open source project 的一部份。應用程式的更新需要一個實作 Omaha Server Protocol 的伺服器。

Omaha 有兩個伺服器組成,autoupdate 及 download。將伺服器責任的分離,是故意的,因為兩個事情的要求不同。下載檔案需要大頻寬,且可容忍高延遲。更新時的要求則是頻率高且低延遲但頻寬要求低。這兩個的不同,使得 google 採取兩個伺服器來滿足需求。

autoupdate 伺服器提供以下功能:

  • 回應來自不同的 Omaha client 的 update ping,告訴它們,是否有更新及如何更新機器上的一批 client 產品。
  • 提供足夠的 configuration schema,讓不同的產品團隊不用實作自己的伺服器。Client 產品應該可提供任意的旗標,讓伺服器在 update ping 傳送時使用,同時讓伺服器根據旗標的出現或不出現做不同的行為反應。
  • 讓 google 在某群穩定的使用者執行實驗測試。例如,某個團隊希望佈署新版產品到 0.01% 的使用者電腦,為期一星期,在全面佈署前可以確認有無不預期的問題。

download 伺服器主要工作是提供位元檔下載。為了提供非公開 beta 及其他有限制軟體的更新,download 伺服器可以限制某些下載的存取。

Rollout Process

為了最大的可擴展性,團隊可以重新設定 update server 的範圍而不會影響到其他團隊。

 

參考:http://omaha.googlecode.com/svn/wiki/OmahaOverview.html

沒有留言:

張貼留言