[英]Azure IoT Edge stop a module programmatically
我正在尝试以编程方式更改 IoT Edge 模块的“状态”(运行或停止)和“restartPolicy”,以便停止模块而不必重新创建设备的整个部署。
我已经看到 Edge Agent 的 Twin 在他的 desiredProperties 中有模块的部署信息,我尝试使用以下代码(使用 Microsoft.Azure.Devices NuGet 包)修补它
public async Task ShutdownModule(string deviceId, string moduleId)
{
var twinEdgeAgent = await _registryManager.GetTwinAsync(deviceId, "$edgeAgent");
var patchJson = $"{{\"properties\":{{\"desired\":{{\"modules\":{{\"{moduleId}\":{{\"status\": \"stopped\", \"restartPolicy\": \"never\"}}}}}}}}}}";
await _registryManager.UpdateTwinAsync(deviceId, "$edgeAgent", patchJson, twinEdgeAgent.ETag);
}
不幸的是,这不起作用,我收到一个UnauthorizedException
消息“ErrorCode:SystemModuleModifyUnauthorizedAccess;Unauthorized to modify reserved module。”。 看起来我无法更改 Edge Agent 模块的所需属性。
有没有办法更改此属性而不必重新创建整个部署 JSON,或者至少有没有办法获取此部署 JSON,以便我可以修改需要更改的属性?
我首先通过 EdgeAgent、EdgeHub 和所有模块双胞胎重建现有部署,通过部署 API 设法做到了这一点。
这是我最终编写的方法的简历:
var modulesContent = new Dictionary<string, IDictionary<string, object>>();
var twinEdgeAgent = await _registryManager.GetTwinAsync(deviceId, "$edgeAgent");
var agentModules = twinEdgeAgent.Properties.Desired[ModulesJsonPropertyName];
agentModules[myModuleId]["status"] = "stopped";
agentModules[myModuleId]["restartPolicy"] = "never";
var desiredProperties = twinEdgeAgent.GetDesiredPropertiesDictionary();
modulesContent.Add("$edgeAgent", edgeHubDesiredProperties);
var twinEdgeHub = await _registryManager.GetTwinAsync(deviceId, "$edgeHub");
var edgeHubDesiredProperties = twinEdgeHub.GetDesiredPropertiesDictionary();
modulesContent.Add("$edgeHub", edgeHubDesiredProperties);
// foreach modules contained in agentModules also add
// the module's twin desired properties in the dictionary (not shown for brevity)
await _registryManager.ApplyConfigurationContentOnDeviceAsync(
deviceId,
new ConfigurationContent { ModulesContent = modulesContent });
internal static class TwinExtensions
{
private const string DesiredPropertiesAttribute = "properties.desired";
public static IDictionary<string, object> GetDesiredPropertiesDictionary(this Twin twin)
{
if (twin == null)
{
throw new ArgumentNullException(nameof(twin));
}
var twinDesiredProperties = twin.Properties.Desired;
twinDesiredProperties.ClearMetadata();
var twinDesiredPropertiesDictionary =
JsonConvert.DeserializeObject<Dictionary<string, object>>(twinDesiredProperties.ToJson());
return new Dictionary<string, object> {{DesiredPropertiesAttribute, twinDesiredPropertiesDictionary}};
}
}
也许有更好/更简单的解决方案,但我们正在使用类似的方法来自动升级模块的运行时映像和其他一些事情,因此我能够在同一代码中重新组合所有这些更改。
如果有一种方法可以直接获取部署 JSON 但我没有找到任何方法,那将会大大简化。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.