如何與 OSConfig 和 Azure IoT 的 CommandRunner 功能互動

OSConfig 公開的大部分裝置屬性都是從實作詳細資料分離和抽象化。 例如,當您使用 HostName.desiredName 來設定裝置的主機名稱時,您不需要擔心作業系統類別、腳本執行時間相依性或計時細微差異。

不過,有時候,您可能想要為彈性提供簡單的交易。 例如:

  • 您需要從裝置擷取自訂資訊 -- 例如,想要從裝置的觀點報告的結果 ping example.com
  • 您必須在沒有現有 OSConfig 所需的/可寫入屬性的裝置上設定某些專案

OSConfig 的 CommandRunner 功能可透過殼層命令/腳本啟用自訂設定和報告。 它也包含某些預先定義的動作 (關機、重新開機) 不需要任何腳本。

提示

本參考文章說明 CommandRunner 概念、互動模型等。如需具體使用範例,請參閱:

互動模型和索引鍵屬性/欄位

互動模型的摘要

雖然本文稍後可能會 (更細微的使用方式,但本文稍後會) 說明,但核心互動模型很簡單:

  • 您可以藉由寫入對應項中的所需 commandArguments 來起始命令要求。
  • 您可以從對應項讀取報告 commandStatus 來取得結果。

顯示 commandArguments 和 commandStatus 的圖表

重要

此圖表中顯示的承載會向下移除,以強調傳入/輸出流程。 如需完整物件模型,包括此處未顯示的必要成員,請參閱: 完整物件模型

往返識別碼為: commandId

在上圖中,請注意 和 commandArgumentscommandStatus 都包含名為 的 commandId 欄位。 這是整個非同步作業中的來回識別碼連結要求和結果。

呼叫端 (系統管理員或系統管理工具鏈) 選擇 commandId 值。

提示

commandId 是 中的必要專案 commandArguments 。 呼叫端通常會在選擇值時使用下列其中一種模式:

  • 第一個要求) 的 「1」 (、第二個要求) 等單調值、「2」 (等。或描述性值,例如 「my_ping_command」

    這些非常適合臨機操作探索;它們不需要規劃,而且可以在編輯對應項內容時輕鬆輸入

  • 高 Entropy 自動產生的值,例如 UUID

    這些非常適合大規模程式設計使用,其中雲端解決方案後端會以程式設計方式建立及追蹤值

的新 commandArguments 值 commandId ,表示這是新的要求。 在單一裝置對應項的內容中,填入新的 commandId 大致類似于在殼層環境中按下 'Enter'。

commandId 也可讓您追蹤多個要求。 每個裝置上的 CommandRunner 可以接收 (,並報告一段時間) 多個要求的狀態。 同時, commandArguments 每個裝置對應項中的 和 commandStatus 元件隨時只能描述一個要求。 commandId 是可讓呼叫端瞭解 (和控制) 呼叫端目前描述 commandStatus 的來回識別碼。 實際上, commandStatus 會傳達「針對識別碼為 'foo' 的要求,狀態為 < ... > 」。

何時 commandStatus 更新?

裝置上的 CommandRunner 有兩個觸發程式可更新 commandStatus 。

  1. 背景重新整理

    commandStatus 會定期更新, (預設值為 30 秒) 。 根據預設,此背景重新整理會導致它代表最近要求的狀態。

    實際上,這表示在透過 commandArguments 提交要求之後,您預期會在大約 30-60 秒後看到 commandStatus 中的對應狀態。

  2. refreshCommandStatus

    refreshCommandStatus 是一種機制,可解決兩個進階使用案例:

    1. 您已透過 commandArguments 發出多個要求,而且想要查看特定要求的狀態,而不是最新的要求
    2. 您不想等待背景重新整理,即使您只對最新的要求感興趣也一樣

    若要觸發此機制,請參閱下方的物件模型檔以取得 commandArguments 。

使用 CommandRunner 進行自訂設定和報告的最佳做法

  1. 大小考量

    針對簡短命令/腳本和簡短輸出,您可以透過對應項直接內嵌工作。 這種方法有優點,特別是在IoT 中樞之外沒有網路或驗證相依性。 此方法的主要缺點是輸入 (包括腳本/命令文字) 和輸出 (包括任何擷取的主控台輸出) 每個限制為 4KB。

    對於較長的腳本,您可以將腳本儲存在其他位置 (,例如 GitHub) ,並從您透過對應項傳遞至 OSConfig 的最低包裝函式命令呼叫該腳本。 如需範例,請參閱: 使用 Azure IoT 和 OSConfig 自訂設定和報告。 與大小無關,您可能也偏好在 GitHub 中管理您的腳本或類似專案,其中只有對應項內容指向這些腳本。

    對於主控台輸出對對應項而言太大的腳本/命令,您可以在腳本中包含邏輯,以將結果傳送至內部部署或雲端儲存體,而不是 stdout。 如需範例,請參閱: 使用 Azure IoT 和 OSConfig 自訂設定和報告。

  2. 使用獨立、非互動式命令/腳本

    比較少的來回行程比較好,一次來回是最好的。 OSConfig 和 CommandRunner 已針對非互動性進行調整優化。 雖然可以序列 (一個命令之後使用 CommandRunner,但與即時同步終端機類似,) 體驗並不最佳。 沒有任何方法可以處理互動式殼層提示,您必須將 指派給 commandId 每個要求、必須等候對應項同步處理等等。

    相反地,請將 CommandRunner 視為大規模達成自訂群組態和報告的方式。 您可以以非同步方式將非互動式腳本 (或預先定義的動作,例如重新開機) 到一部裝置或數百萬個裝置,即使它們隨著時間演進,也可以回報結果, (隨著時間演進,因為新裝置加入車隊,例如) 。

    換句話說,假設您需要在西班牙的所有目前和未來的 Ubuntu 20.04 裝置上執行四個命令。 請勿將它視為 CommandRunner 的 4 個離散循序用法,請將它視為 CommandRunner 的單一用法,其中承載包含您的四個命令。 同時,IoT 中樞組態之類的雲端工作流程可確保這會分散到所有目前和未來的裝置,而這些裝置應位於範圍內。

完整物件模型

重要

版本 1.0.3 (于 2022 年 6 月發行 28 日,) 包含可能影響現有使用者之成員名稱的重大變更。 如需詳細資訊,請參閱: 成員名稱在 1.0.3 版中從 PascalCase 轉換為 camelCase

下列資訊適用于物件模型的純預期/報告檢視,以及 DTDL 增強型檢視。 如需詳細資訊,請參閱 OSConfig 使用者需要知道有關「一般所需/報告」與「DTDL 增強」工具鏈的事項。

commandArguments (由系統管理員) 設定

  • 描述:從系統管理員輸入、觸發新的命令要求,或觸發 commandStatus 的重新整理。

  • 路徑: properties.desired.CommandRunner.commandArguments (CommandRunner 元件 -- >commandArguments 可寫入的屬性)

  • 成員

    名稱 類型 注意
    commandId string • 呼叫端指定的要求識別碼;如需背景,請參閱上方
    • 當 commandId 空白時,會忽略 commandArguments
    • 如需 commandId 與動作之間的互動,請參閱下列內容
    動作 enum/int 下列專案應該與 commandId 的新值結合:
    • 1 (重新開機)
    • 2 (關機)
    • 3 (runCommand) ;起始自訂群組態或報告的殼層命令/腳本

    下列專案應該與先前使用的 CommandID 結合:
    • 4 (refreshCommandStatus) 會導致 commandStatus 描述 commandId 所識別的特定要求
    引數 字串 • 當動作為 1 (重新開機) 或 2 (關機) 時,觸發動作之前要延遲的選擇性秒數
    • 當動作為 3 (RunCommand) 時,要執行的命令列,例如 ping -c 2 example.com
    • 忽略任何其他動作類型
    • commandArguments 的大小 (通常由 Azure IoT 對應項中的引數文字) 所主導,限制為 4KB;如需較長的腳本,請參閱 良好作法
    singleLineTextResult boolean • 當動作為 3 (RunCommand) 時,選擇性切換以指定是否應該從主控台輸出移除分行符號
    • 忽略任何其他動作類型
    timeout int • 當動作為 3 (runCommand) 時,長時間執行的要求會在這段數秒後終止
    • 選擇性 (預設值為 30)
    • 忽略任何其他動作類型
  • 來自IoT 中樞和真實裝置的範例

    • 重新開機要求:

      "CommandRunner": {
         "__t": "c",
         "commandArguments": {
            "commandId": "my_reboot_cmd",
            "arguments": "",
            "timeout": 30,
            "singleLineTextResult": false,
            "action": 1
         }
      }
      
    • 自訂群組態 (時區) 要求:

      "CommandRunner": {
         "__t": "c",
         "commandArguments": {
            "commandId": "my_timezone_cmd",
            "arguments": "timedatectl set-timezone Etc/UTC; timedatectl | grep Time",
            "timeout": 30,
            "singleLineTextResult": false,
            "action": 3
         }
      }
      
    • 如需其他範例,請參閱:

commandArguments 從裝置) (通知

  • 描述:這是裝置上 OSConfig 代理程式的通知,其已從系統管理員端收到 commandArguments 值

  • 路徑: properties.reported.CommandRunner.commandArguments (可寫入屬性的 commandArguments 裝置通知部分)

  • 成員:

    名稱 類型 注意
    value map 應該鏡像 properties.desired.CommandRunner.commandArguments ,指出裝置在線上且已收到要求
    ac int 狀態碼,小寫為值 200

commandStatus

  • 描述:提供先前透過 commandArguments 提交之要求的狀態和輸出

  • 路徑: properties.reported.CommandRunner.commandStatus (CommandRunner 元件 -- >commandStatus 唯讀屬性)

  • 成員

    名稱 類型 注意
    commandId string • 識別 Commandstatus 目前描述哪些先前收到的要求
    • 根據預設,表示最新的要求
    • 呼叫端可以變更此焦點,透過上述 refreshCommandStatus 機制來描述特定要求
    ResultCode int 所要求命令的結束代碼。 echo $?類似于 bash 中的
    currentState enum/int • 小寫是值 2 (succeeded)
    • 如需可能值的完整清單,請參閱中繼資料
    textResult string • 所要求命令的主控台輸出
    • commandStatus 的大小 (通常由 Azure IoT 對應項中的 textResult 元件) 所主導,限制為 4KB;如需較長的輸出,請參閱 良好作法
  • 來自IoT 中樞和真實裝置的範例

重要

1.0.3 版 (于 2022 年 6 月 28 日發行,) 包含可能影響現有使用者的成員名稱重大變更。 如需詳細資訊,請參閱: 成員名稱在 1.0.3 版中從 PascalCase 轉換為 camelCase

下一步

如需 OSConfig 案例和功能的概觀,請參閱:

如需特定實際範例,請參閱: