Skip to content

RFC: INSTCMD and SET VAR status tracking #656

Open
@aquette

Description

@aquette

Dear fellows,
I'm happy to finally be able to provide a RFC for this long awaited feature!
(esp. @clepple , @zykh , @jimklimov)

From docs/net-protocol.txt, Future ideas -> Command status:

After sending an INSTCMD or SET, a client will eventually be able to poll to see whether it was completed successfully by the driver.

Proposal:

  • Add a new "CMDSET_STATUS" command in the network protocol to enable/disable
    the feature and provide status tracking information upon request:

    • docs/net-protocol.txt additions

      SET CMDSET_STATUS

      
      Form:
      
          SET CMDSET_STATUS "<value>"
          SET CMDSET_STATUS ON
          SET CMDSET_STATUS OFF
      
      Response:
      
          OK
          ERR INVALID-ARGUMENT (if "value" is not "ON" or "OFF")
          ERR USERNAME-REQUIRED (if not yet authenticated)
          ERR PASSWORD-REQUIRED (if not yet authenticated)
      
      
      GET CMDSET_STATUS
      

      Form:

      GET CMDSET_STATUS               (activation status of CMDSET_STATUS)
      GET CMDSET_STATUS [<status_id>] (execution status of a command / setvar) 
      GET CMDSET_STATUS 1bd31808-cb49-4aec-9d75-d056e6f018d2
      

      Response:

      PENDING              (command execution is pending)
      SUCCESS              (command was successfully executed)
      ERR UNKNOWN          (command execution failed with unknown error)
      ERR INVALID-ARGUMENT (command execution failed due to missing or invalid argument)
      ERR FAILED           (command execution failed)
      
  • whenever CMDSET_STATUS is enabled, and a valid command / setvar is received by upsd,
    upsd will allocate an ID (UUID v4 random, see below notes) and forward to driver
    the request with the additional STATUS_ID tag and ID parameter

    • docs/sock-protocol.txt additions

      Commands sent by the server

      INSTCMD

      
          INSTCMD <cmdname> [cmdparam] [STATUS_ID <ID>]
      
          INSTCMD panel.test.start
          INSTCMD load.off 10 
          INSTCMD load.on 10 STATUS_ID 1bd31808-cb49-4aec-9d75-d056e6f018d2
      
      
    • NOTE:

      • cmdparam is an additional and optional parameter for the command,
      • "STATUS_ID " can be provided to track commands execution status, if
        CMDSET_STATUS was set to ON on upsd. In this case, driver will later return
        the execution status, using STATUS_ID
  • driver receives the cmd / setvar request from upsd. Then, upon completion of
    this action, driver sends back the status with the ID (using CMDSET_STATUS) and
    forgets about it (managed at the dstate level and not provided to upshandlers)

    • docs/sock-protocol.txt additions

      Commands used by the drivers

      CMDSET_STATUS

      
          CMDSET_STATUS <ID> <value>
      
      This is sent in response to an INSTCMD or SET VAR that includes a STATUS_ID,
      upon completion of request execution by the driver. <value> is the integer
      return value from the driver handlers instcmd and setvar (see
      drivers/upshandler.h). The server is in charge of translating these codes into
      strings, as per docs/net-protocol.txt GET CMDSET_STATUS.
      
      
      
  • upsd receives the status of the command / settings and updates the matching
    status tracking entry

  • upsd deletes tracked IDs upon time based (execution timestamp + CMDSETSTATUSDELAY in upsd.conf)

Notes:

  • A working implementation is available as https://github.com/networkupstools/nut/tree/cmdset_status

  • This work is sponsored by Eaton

  • I'm not fan of the CMDSET_STATUS name, but had no better idea apart from
    STATUS_TRACKING / STATUS_ID. Comments and proposal welcome!

  • the modifications are:

    • non regressive: if CMDSET_STATUS is not enabled, the protocol will behave as
      usual. Hence, existing implementation will not be altered
    • not impacting other clients: though the tracking structure is global (to
      avoid loss of info when clients disconnect), only client that enabled
      CMDSET_STATUS will receive the ID and be able to query the status info
    • mainly supported by upsd, its sstate and netcmds layer
    • limited to dstate for drivers. No other modification are
      needed in the drivers or elsewhere
  • ID generation: I've selected UUID v4 (random) to ensure uniqueness of the
    generated ID. For now, I've added a basic implementation in the code, but it's
    limited in OS scope, which I plan to address more cleanly. My requirements are:

  • There are other remainders to be addressed for a full completion, but which can be separe work):

    • Augeas completion for CMDSETSTATUSDELAY
    • upscmd
    • upsrw
    • libnutclient (@boricj will very probably handle this)
    • Python
    • Perl
    • jNUT (@EmilienKia)
    • anything I missed?

Testing procedure:

telnet localhost 3493

  • authenticate using

USERNAME "username from upsd.users"
PASSWORD "password from upsd.users"

  • check if status tracking is enabled:

GET CMDSET_STATUS

will return:

OFF

  • enable status tracking using:

SET CMDSET_STATUS ON

  • issue an instant command or variable setting. For example:

INSTCMD myups load.off

You will receive back an "OK" answer with a status ID:

OK d6470a8e-4521-411c-beef-69cc9b33a94b

  • Ask for the status of this command using:

GET CMDSET_STATUS d6470a8e-4521-411c-beef-69cc9b33a94b

  • You will receive an answer like:

SUCCESS

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions