如何使用AWS命令列介面設定本機資源存取 - AWS IoT Greengrass

AWS IoT Greengrass Version 1 於 2023 年 6 月 30 日進入延長使用壽命階段。如需詳細資訊,請參閱AWS IoT Greengrass V1 維護政策。在此日期之後, AWS IoT Greengrass V1 將不會發行提供功能、增強功能、錯誤修正或安全性修補程式的更新。在上運行的設備 AWS IoT Greengrass V1 不會中斷,並將繼續運行並連接到雲。我們強烈建議您移轉至 AWS IoT Greengrass Version 2,這會增加重要的新功能,並支援其他平台

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

如何使用AWS命令列介面設定本機資源存取

此功能適用於AWS IoT Greengrass核心 v1.3 及更高版本。

若要使用本機資源,您必須新增資源定義至部署到 Greengrass 核心裝置的群組定義中。群組定義必須在授與 Lambda 函數存取本機資源許可的地方含有 Lambda 函數定義。如需包括要求和限制的詳細資訊,請參閱使用 Lambda 函數和連接器存取本機資源

本教學課程說明建立本機資源並使用 AWS Command Line Interface (CLI) 設定對其存取權的程序。為了執行教學課程中的步驟,您必須已經建立 AWS IoT Greengrass 入門 中所述的 Greengrass 群組。

有關如何使用 AWS Management Console 的教學課程,請參閱如何使用 AWS Management Console 設定本機資源存取

建立本機資源

首先,請您使用 CreateResourceDefinition 命令建立資源定義,以指定要存取的資源。在此範例中,我們將建立兩個資源,TestDirectoryTestCamera

aws greengrass create-resource-definition --cli-input-json '{ "Name": "MyLocalVolumeResource", "InitialVersion": { "Resources": [ { "Id": "data-volume", "Name": "TestDirectory", "ResourceDataContainer": { "LocalVolumeResourceData": { "SourcePath": "/src/LRAtest", "DestinationPath": "/dest/LRAtest", "GroupOwnerSetting": { "AutoAddGroupOwner": true, "GroupOwner": "" } } } }, { "Id": "data-device", "Name": "TestCamera", "ResourceDataContainer": { "LocalDeviceResourceData": { "SourcePath": "/dev/video0", "GroupOwnerSetting": { "AutoAddGroupOwner": true, "GroupOwner": "" } } } } ] } }'

資源:Greengrass 群組中的 Resource 物件清單。一個 Greengrass 群組最多可有 50 個資源。

Resource#Id:資源的唯一識別符。此 ID 用於查閱 Lambda 函數組態裡的資源。最大長度 128 個字元。模式:[a-zA-Z0-9:_-]+。

Resource#Name:資源的名稱。在 Greengrass 主控台中顯示的資源名稱。最大長度 128 個字元。模式:[a-zA-Z0-9:_-]+。

LocalDeviceResourceData# SourcePath:裝置資源的本機絕對路徑。裝置資源的來源路徑可以只參閱在 /dev 下的字元裝置或區塊型儲存設備。

LocalVolumeResourceData# SourcePath:Greengrass 核心裝置上磁碟區資源的本機絕對路徑。此位置位於函數執行所在的容器外。磁碟區資源類型的來源路徑不能以 /sys 為開頭。

LocalVolumeResourceData# DestinationPath:Lambda 環境中磁碟區資源的絕對路徑。此位置位於函數執行所在的容器內。

GroupOwnerSetting:可讓您為 Lambda 程序設定其他群組權限。此欄位為選用欄位。如需詳細資訊,請參閱 群組擁有者檔案存取許可

GroupOwnerSetting# AutoAddGroupOwner:如果為 true,Greengrass 會自動將資源的指定 Linux 作業系統群組擁有者新增至 Lambda 程序權限。因此,Lambda 程序對新增的 Linux 群組具有檔案存取許可。

GroupOwnerSetting# GroupOwner ︰指定其權限新增至 Lambda 處理序的 Linux 作業系統群組的名稱。此欄位為選用欄位。

資源定義版本 ARN 會由 CreateResourceDefinition 傳回。應使用 ARN 更新群組定義。

{ "LatestVersionArn": "arn:aws:greengrass:us-west-2:012345678901:/greengrass/definition/resources/ab14d0b5-116e-4951-a322-9cde24a30373/versions/a4d9b882-d025-4760-9cfe-9d4fada5390d", "Name": "MyLocalVolumeResource", "LastUpdatedTimestamp": "2017-11-15T01:18:42.153Z", "LatestVersion": "a4d9b882-d025-4760-9cfe-9d4fada5390d", "CreationTimestamp": "2017-11-15T01:18:42.153Z", "Id": "ab14d0b5-116e-4951-a322-9cde24a30373", "Arn": "arn:aws:greengrass:us-west-2:123456789012:/greengrass/definition/resources/ab14d0b5-116e-4951-a322-9cde24a30373" }

建立 Greengrass 函數

建立資源後,請使用 CreateFunctionDefinition 命令建立 Greengrass 函數並授與該函數存取資源的權限:

aws greengrass create-function-definition --cli-input-json '{ "Name": "MyFunctionDefinition", "InitialVersion": { "Functions": [ { "Id": "greengrassLraTest", "FunctionArn": "arn:aws:lambda:us-west-2:012345678901:function:lraTest:1", "FunctionConfiguration": { "Pinned": false, "MemorySize": 16384, "Timeout": 30, "Environment": { "ResourceAccessPolicies": [ { "ResourceId": "data-volume", "Permission": "rw" }, { "ResourceId": "data-device", "Permission": "ro" } ], "AccessSysfs": true } } } ] } }'

ResourceAccessPolicies:包含resourceIdpermission授與 Lambda 函數存取資源的權限。一個 Lambda 函數最多可以存取 20 個資源。

ResourceAccessPolicy#Permission: 指定 Lambda 函數對資源擁有的權限。可行的選項為 rw (讀取/寫入) 或 ro (唯讀)。

AccessSysfs:如果為 true,則 Lambda 程序可以對 Greengrass 核心裝置上的/sys資料夾具有讀取權限。這在 Greengrass Lambda 函數需要從中讀取設備信息的情況下使用。/sys

同樣地,CreateFunctionDefinition 會傳回一個函數定義版本 ARN。此 ARN 應於您的群組定義版本中使用。

{ "LatestVersionArn": "arn:aws:greengrass:us-west-2:012345678901:/greengrass/definition/functions/3c9b1685-634f-4592-8dfd-7ae1183c28ad/versions/37f0d50e-ef50-4faf-b125-ade8ed12336e", "Name": "MyFunctionDefinition", "LastUpdatedTimestamp": "2017-11-22T02:28:02.325Z", "LatestVersion": "37f0d50e-ef50-4faf-b125-ade8ed12336e", "CreationTimestamp": "2017-11-22T02:28:02.325Z", "Id": "3c9b1685-634f-4592-8dfd-7ae1183c28ad", "Arn": "arn:aws:greengrass:us-west-2:123456789012:/greengrass/definition/functions/3c9b1685-634f-4592-8dfd-7ae1183c28ad" }

將 Lambda 函數新增至群組

最後,請使用 CreateGroupVersion 新增函數至群組。例如:

aws greengrass create-group-version --group-id "b36a3aeb-3243-47ff-9fa4-7e8d98cd3cf5" \ --resource-definition-version-arn "arn:aws:greengrass:us-west-2:123456789012:/greengrass/definition/resources/db6bf40b-29d3-4c4e-9574-21ab7d74316c/versions/31d0010f-e19a-4c4c-8098-68b79906fb87" \ --core-definition-version-arn "arn:aws:greengrass:us-west-2:123456789012:/greengrass/definition/cores/adbf3475-f6f3-48e1-84d6-502f02729067/versions/297c419a-9deb-46dd-8ccc-341fc670138b" \ --function-definition-version-arn "arn:aws:greengrass:us-west-2:123456789012:/greengrass/definition/functions/d1123830-da38-4c4c-a4b7-e92eec7b6d3e/versions/a2e90400-caae-4ffd-b23a-db1892a33c78" \ --subscription-definition-version-arn "arn:aws:greengrass:us-west-2:123456789012:/greengrass/definition/subscriptions/7a8ef3d8-1de3-426c-9554-5b55a32fbcb6/versions/470c858c-7eb3-4abd-9d48-230236bfbf6a"
注意

若要了解如何取得群組 ID 來與此命令搭配使用,請參閱 取得群組 ID

會傳回一個新的版本:

{ "Arn": "arn:aws:greengrass:us-west-2:012345678901:/greengrass/groups/b36a3aeb-3243-47ff-9fa4-7e8d98cd3cf5/versions/291917fb-ec54-4895-823e-27b52da25481", "Version": "291917fb-ec54-4895-823e-27b52da25481", "CreationTimestamp": "2017-11-22T01:47:22.487Z", "Id": "b36a3aeb-3243-47ff-9fa4-7e8d98cd3cf5" }

您的 Greengrass 群組現在包含可存取兩個資源的 LraTest Lambda 函數:和. TestDirectory TestCamera

此範例 Lambda 函數「lraTest.py」,以 Python 寫入本機磁碟區資源:

# Demonstrates a simple use case of local resource access. # This Lambda function writes a file test to a volume mounted inside # the Lambda environment under destLRAtest. Then it reads the file and # publishes the content to the AWS IoT LRAtest topic. import sys import greengrasssdk import platform import os import logging # Setup logging to stdout logger = logging.getLogger(__name__) logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) # Create a Greengrass Core SDK client. client = greengrasssdk.client('iot-data') volumePath = '/dest/LRAtest' def function_handler(event, context): try: client.publish(topic='LRA/test', payload='Sent from AWS IoT Greengrass Core.') volumeInfo = os.stat(volumePath) client.publish(topic='LRA/test', payload=str(volumeInfo)) with open(volumePath + '/test', 'a') as output: output.write('Successfully write to a file.') with open(volumePath + '/test', 'r') as myfile: data = myfile.read() client.publish(topic='LRA/test', payload=data) except Exception as e: logger.error('Failed to publish message: ' + repr(e)) return

這些命令由 Greengrass API 提供,建立與管理資源定義和資源定義版本:

故障診斷

  • 問:為什麼我的 Greengrass 群組部署失敗,發生與以下類似的狀況:

    group config is invalid: ggc_user or [ggc_group root tty] don't have ro permission on the file: /dev/tty0

    答: 此失敗狀況表示 Lambda 程序並沒有存取指定資源的許可。解決方法為變更資源的檔案許可權限,讓 Lambda 可以存取即可。(如需詳細資訊,請參閱群組擁有者檔案存取許可)。

  • 問:當我將 /var/run 設為磁碟區資源時,為什麼 Lambda 函數無法啟動,並在 runtime.log 出現錯誤訊息:

    [ERROR]-container_process.go:39,Runtime execution error: unable to start lambda container. container_linux.go:259: starting container process caused "process_linux.go:345: container init caused \"rootfs_linux.go:62: mounting \\\"/var/run\\\" to rootfs \\\"/greengrass/ggc/packages/1.3.0/rootfs_sys\\\" at \\\"/greengrass/ggc/packages/1.3.0/rootfs_sys/run\\\" caused \\\"invalid argument\\\"\""

    答:AWS IoT Greengrass核心目前不支援/var/var/run/var/lib作為磁碟區資源的組態。一種解決方法是首先在另一個文件中掛載 /var/var/run/var/lib,然後再設定此資料夾做為磁碟區資源。

  • 問:當我將 /dev/shm 設為唯讀許可的磁碟區資源時,為什麼 Lambda 函數無法啟動,並在 runtime.log 出現錯誤訊息:

    [ERROR]-container_process.go:39,Runtime execution error: unable to start lambda container. container_linux.go:259: starting container process caused "process_linux.go:345: container init caused \"rootfs_linux.go:62: mounting \\\"/dev/shm\\\" to rootfs \\\"/greengrass/ggc/packages/1.3.0/rootfs_sys\\\" at \\\"/greengrass/ggc/packages/1.3.0/rootfs_sys/dev/shm\\\" caused \\\"operation not permitted\\\"\""”

    答: /dev/shm 因為只能設定成 [讀取/寫入]。變更資源許可為 rw 以解決此問題。