Como interagir com a funcionalidade CommandRunner do OSConfig e do Azure IoT

A maioria das propriedades do dispositivo expostas pelo OSConfig são discretas e abstraídas dos detalhes de implementação. Por exemplo, quando utiliza HostName.desiredName para definir o nome de anfitrião de um dispositivo, não precisa de se preocupar com o sabor do sistema operativo, com as dependências de runtime de scripting ou com as nuances de temporização.

No entanto, por vezes, poderá querer trocar simplicidade por flexibilidade. Por exemplo:

  • Tem de obter informações personalizadas do dispositivo, como querer comunicar os resultados da ping example.com perspetiva do dispositivo
  • Tem de configurar algo no dispositivo onde não existe nenhuma propriedade pretendida/gravável do OSConfig

A funcionalidade CommandRunner do OSConfig permite a configuração personalizada e os relatórios através de comandos/scripts da shell. Também inclui determinadas ações predefinidas (encerramento, reinício) que não requerem scripts.

Dica

Este artigo de referência descreve os conceitos de CommandRunner, o modelo de interação, etc. Para obter exemplos de utilização concreta, veja:

O modelo de interação e as propriedades/campos da chave

Resumo do modelo de interação

Embora seja possível utilizar mais nuances (e descrito mais adiante neste artigo), o modelo de interação principal é simples:

  • Inicia um pedido de comando ao escrever no duplo.commandArguments
  • Obtém os resultados ao ler comunicados commandStatus a partir do duplo.

Diagrama a mostrar commandArguments e commandStatus

Importante

Os payloads apresentados neste diagrama são removidos para realçar o fluxo de entrada/saída. Para o modelo de objeto completo, incluindo os membros necessários não apresentados aqui, veja: O modelo de objeto completo

O identificador de ida e volta é: commandId

No diagrama acima, tenha em atenção que tanto commandArguments e commandStatus incluem um campo chamado commandId. Este é o identificador de ida e volta que liga o pedido e o resultado ao longo desta operação assíncrona.

O autor da chamada (administrador ou cadeia de ferramentas de administrador) escolhe o valor commandId.

Dica

commandId é necessário em commandArguments. Normalmente, os autores de chamadas utilizam um destes padrões ao escolher valores:

  • Valores monotónicos como "1" (para o primeiro pedido), "2" (para segundo pedido), etc. ou valores descritivos como "my_ping_command"

    Estes são adequados para exploração ad hoc; não precisam de planeamento e podem ser escritos facilmente ao editar conteúdos de duplos

  • Valores gerados automaticamente de elevada entropia, como UUIDs

    Estes são adequados para uma utilização programática em grande escala, onde um back-end de solução cloud irá criar e controlar programaticamente os valores

Um novo valor de commandId em commandArguments indica que se trata de um novo pedido. No contexto do duplo de um único dispositivo, preencher um novo commandId é aproximadamente análogo a premir "Enter" num ambiente de shell.

commandId também permite controlar vários pedidos. CommandRunner em cada dispositivo pode receber (e reportar estado em) vários pedidos ao longo do tempo. Entretanto, os commandArguments componentes e commandStatus no duplo de cada dispositivo só podem descrever um pedido a qualquer momento. commandId é o identificador de ida e volta que permite que o autor da chamada compreenda (e controle) qual o pedido anterior descrito atualmente por commandStatus. Na verdade, commandStatus comunica "para o seu pedido em que o ID era 'foo', o estado é <...>".

Quando é commandStatus atualizado?

Existem dois acionadores para CommandRunner no dispositivo atualizar commandStatus.

  1. Atualização em segundo plano

    commandStatus é atualizado num intervalo regular (a predefinição é 30 segundos). Por predefinição, esta atualização em segundo plano faz com que represente o estado do pedido mais recente.

    Na prática, isto significa que, após submeter um pedido através de commandArguments, pode esperar ver o estado correspondente em commandStatus após aproximadamente 30 a 60 segundos.

  2. refreshCommandStatus

    refreshCommandStatus é um mecanismo que aborda dois casos de utilização avançados:

    1. Emitiu vários pedidos ao longo do tempo através commandArgumentsde e quer ver o estado de um pedido específico e não o pedido mais recente
    2. Não quer esperar pela atualização em segundo plano, mesmo que só esteja interessado no pedido mais recente

    Para acionar este mecanismo, veja a documentação do modelo de objeto abaixo para commandArguments.

Boas práticas para configuração personalizada e relatórios com CommandRunner

  1. Considerações sobre o tamanho

    Para comandos/scripts curtos e saídas curtas, pode trabalhar diretamente inline através do duplo. Esta abordagem tem vantagens, especialmente sem dependência de rede ou autenticação fora do Hub IoT. A principal desvantagem desta abordagem é que as entradas (incluindo o texto do script/comandos) e as saídas (incluindo qualquer saída de consola capturada) estão limitadas a 4 KB.

    Para scripts mais longos, pode armazenar o script noutro local (como o GitHub) e chamá-lo a partir de um comando de wrapper mínimo que transmite ao OSConfig através do duplo. Para obter exemplos, veja: Configuração personalizada e relatórios com o Azure IoT e o OSConfig. Independentemente do tamanho, também pode preferir gerir os seus scripts no GitHub ou semelhantes, com os conteúdos duplos a apontarem simplesmente para os mesmos.

    Para scripts/comandos cuja saída da consola é demasiado grande para o duplo, pode incluir lógica no script para enviar resultados para o armazenamento no local ou na cloud em vez de para stdout. Para obter exemplos, veja: Configuração personalizada e relatórios com o Azure IoT e o OSConfig.

  2. Utilizar comandos/scripts independentes e não interativos

    Menos viagens de ida e volta são melhores, uma viagem de ida e volta é a melhor. OSConfig e CommandRunner estão otimizados para dimensionamento e não interatividade. Embora seja possível utilizar CommandRunner em série (um comando após o outro, semelhante a um terminal síncrono em direto), a experiência não é ideal. Não existe forma de processar pedidos de shell interativos, tem de atribuir um commandId a cada pedido, tem de aguardar pela sincronização de duplos, etc.

    Em vez disso, pense no CommandRunner como uma forma de alcançar a configuração personalizada e os relatórios em escala. Pode distribuir de forma assíncrona um script não interativo (ou uma ação predefinida como reiniciar) para um dispositivo ou milhões de dispositivos e pode comunicar os resultados mesmo à medida que evoluem ao longo do tempo (à medida que novos dispositivos se juntam à frota, por exemplo).

    Por outras palavras, digamos que precisa de executar quatro comandos em todos os dispositivos Ubuntu 20.04 atuais e futuros em Espanha. Não pense nisso como 4 utilizações sequenciais discretas de CommandRunner, pense nela como uma única utilização de CommandRunner, onde o payload contém os seus quatro comandos. Entretanto, um fluxo de trabalho na cloud, como o Hub IoT Configurations, pode garantir que este é distribuído por todos os dispositivos atuais e futuros que devem estar no âmbito.

O modelo de objeto completo

Importante

A versão 1.0.3 (publicada a 28 de junho de 2022) inclui alterações interruptivas aos nomes dos membros que podem afetar os utilizadores existentes. Para obter mais informações, consulte: Transição de nomes de membros de PascalCase para camelCase na versão 1.0.3

As seguintes informações aplicam-se a vistas pretendidas/comunicadas simples do modelo de objeto, bem como a vistas melhoradas de DTDL. Para obter mais informações, veja What OSConfig users need to know about "plain desired/reported" vs .DTDL enhanced" toolchains (O que os utilizadores do OSConfig precisam de saber sobre as tabelas de ferramentas "pretendidas/reportadas simples" vs. "otimizadas para DTDL".

commandArguments (definido pelo administrador)

  • Descrição: a entrada do administrador aciona um novo pedido de comando ou aciona a atualização de commandStatus.

  • Caminho: properties.desired.CommandRunner.commandArguments (CommandRunner componente -->commandArguments propriedade gravável)

  • Membros

    Nome Tipo Notas
    commandId string • ID do pedido especificado pelo autor da chamada; veja acima para obter o fundo
    • commandArguments é ignorado quando commandId está em branco
    • Para a interação entre o commandId e a ação, veja o seguinte
    action enumeração/int O seguinte deve ser associado a um novo valor de commandId:
    • 1 (reinício)
    • 2 (encerramento)
    • 3 (executarComando); inicia o comando/script da shell para a configuração ou relatórios personalizados

    O seguinte deve ser associado a um CommandID utilizado anteriormente:
    • 4 (refreshCommandStatus) faz com que commandStatus descreva um pedido específico identificado pelo commandId
    argumentos string • Quando a ação é 1 (reinício) ou 2 (encerramento), um número opcional de segundos para atrasar antes de acionar a ação
    • Quando a ação é 3 (ExecutarComando), a linha de comandos a executar, por exemplo ping -c 2 example.com
    • Ignorado para qualquer outro tipo de ação
    • Tamanho dos comandosArguments (normalmente dominados por texto de argumentos) em duplos IoT do Azure limitados a 4KB; para scripts mais longos, veja Boas práticas
    singleLineTextResult boolean • Quando a ação é 3 (RunCommand), o botão de alternar opcional para especificar se as novas linhas devem ser removidas da saída da consola
    • Ignorado para qualquer outro tipo de ação
    tempo limite int • Quando a ação é 3 (executarComando), os pedidos de execução prolongada são eliminados após estes muitos segundos
    • Opcional (a predefinição é 30)
    • Ignorado para qualquer outro tipo de ação
  • Exemplos de dispositivos Hub IoT e reais

commandArguments (confirmação do dispositivo)

  • Descrição: esta é a confirmação do agente OSConfig no dispositivo de que recebeu o valor commandArguments do lado do administrador

  • Caminho: properties.reported.CommandRunner.commandArguments (a parte de confirmação do dispositivo da commandArguments propriedade gravável)

  • Membros:

    Nome Tipo Notas
    valor mapa Deve espelhar properties.desired.CommandRunner.commandArguments, indicando o dispositivo online e recebeu o pedido
    ac int Código de estado, caso nominal é valor 200

commandStatus

  • Descrição: fornece o estado e a saída de um pedido submetido anteriormente através de commandArguments

  • Caminho: properties.reported.CommandRunner.commandStatus (CommandRunner componente -->commandStatus propriedade só de leitura)

  • Membros

    Nome Tipo Notas
    commandId string • Identifica o pedido recebido anteriormente descrito por Commandstatus
    • Por predefinição, o pedido mais recente está representado
    • O autor da chamada pode alterar este foco para descrever um pedido específico através do mecanismo refreshCommandStatus descrito acima
    resultCode int O código de saída do comando pedido. Análogo ao echo $? bash
    currentState enum/int • Caso nominal é valor 2 (succeeded)
    • Veja os metadados para obter a lista completa dos valores possíveis
    textResult string • O resultado da consola do comando pedido
    • Tamanho dos comandosStatus (normalmente dominado pelo componente textResult) em duplos IoT do Azure limitados a 4KB; para saídas mais longas, veja Boas práticas
  • Exemplos de dispositivos Hub IoT e reais

Importante

A versão 1.0.3 (publicada a 28 de junho de 2022) inclui alterações interruptivas aos nomes de membros que podem afetar os utilizadores existentes. Para obter mais informações, consulte: Transição de nomes de membros de PascalCase para camelCase na versão 1.0.3

Passos seguintes

Para obter uma descrição geral dos cenários e capacidades do OSConfig, veja:

Para obter exemplos práticos específicos, consulte: