Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Running from API throws error that action could not be found #305

Open
nickconway opened this issue May 4, 2024 · 4 comments
Open

Running from API throws error that action could not be found #305

nickconway opened this issue May 4, 2024 · 4 comments
Labels

Comments

@nickconway
Copy link

nickconway commented May 4, 2024

What seems to be the problem?!

When attempting to run an action from the API, sometimes an error is thrown that no action could be found with a blank action title.

Can you provide a sosreport?

# Build: 
commit: f467c69
version: 2024.04.28
date: "2024-04-28T08:55:40Z"

# Runtime:
os: linux
osreleaseprettyname: PRETTY_NAME="Fedora Linux 38 (Container Image)"
arch: amd64
incontainer: true
lastbrowseruseragent: ""

# Config:
countofactions: 1
countofdashboards: 0
loglevel: DEBUG
listenaddresssinglehttpfrontend: 0.0.0.0:1337
listenaddresswebui: localhost:1340
listenaddressrestactions: localhost:1338
listenaddressgrpcactions: localhost:1339
timezone: Local

What package/file/container did you use to install OliveTin?

Docker container - jamesread/olivetin:latest

Your config.yaml

Please copy-paste your config.yaml here

# There is a built-in micro proxy that will host the webui and REST API all on
# one port (this is called the "Single HTTP Frontend") and means you just need
# one open port in the container/firewalls/etc.
#
# Listen on all addresses available, port 1337
listenAddressSingleHTTPFrontend: 0.0.0.0:1337

# insecureAllowDumpSos: true

# Choose from INFO (default), WARN and DEBUG
logLevel: "DEBUG"

# Actions are commands that are executed by OliveTin, and normally show up as
# buttons on the WebUI.
#
# Docs: https://docs.olivetin.app/create-your-first-action.html
actions:
  - title: Update Containers
    id: updateContainers
    icon: restart
    shell: ssh {{ hostname }} -o StrictHostKeyChecking=no '.local/bin/update-containers &> /tmp/update-containers.log'
    timeout: 600
    popupOnStart: execution-dialog
    arguments:
      - name: hostname
        title: Hostname
        type: ascii_identifier

  # Lastly, you can hide actions from the web UI, this is useful for creating
  # background helpers that execute only on startup or a cron, for updating
  # entity files.

  # - title: Update container entity file
  #   shell: 'docker ps -a --format json > /etc/OliveTin/entities/containers.json'
  #   hidden: true
  #   execOnStartup: true
  #   execOnCron: '*/1 * * * *'

# An entity is something that exists - a "thing", like a VM, or a Container
# is an entity. OliveTin allows you to then dynamically generate actions based
# around these entities.
#
# This is really useful if you want to generate wake on lan or poweroff actions
# for `server` entities, for example.
#
# A very popular use case that entities were designed for was for `container`
# entities - in a similar way you could generate `start`, `stop`, and `restart`
# container actions.
#
# Entities are just loaded fome files on disk, OliveTin will also watch these
# files for updates while OliveTin is running, and update entities.
#
# Entities can have properties defined in those files, and those can be used
# in your configuration as variables. For example; `container.status`,
# or `vm.hostname`.
#
# Docs: http://docs.olivetin.app/entities.html
# entities:
#   # YAML files are the default expected format, so you can use .yml or .yaml,
#   # or even .txt, as long as the file contains valid a valid yaml LIST, then it
#   # will load properly.
#   #
#   # Docs: https://docs.olivetin.app/entities.html
#   - file: entities/servers.yaml
#     name: server
#
#   - file: entities/containers.json
#     name: container
#
# # Dashboards are a way of taking actions from the default "actions" view, and
# # organizing them into groups - either into folders, or fieldsets.
# #
# # The only way to properly use entities, are to use them with a `fieldset` on
# # a dashboard.
# dashboards:
#   # Top level items are dashboards.
#   - title: My Servers
#     contents:
#       # The contents of a dashboard will try to look for an action with a
#       # matching title IF the `contents: ` property is empty.
#       - title: Ping All Servers
#
#       # If you create an item with some "contents:", OliveTin will show that as
#       # directory.
#       - title: Hypervisors
#         contents:
#           - title: Ping hypervisor1
#           - title: Ping hypervisor2
#
#       # If you specify `type: fieldset` and some `contents`, it will show your
#       # actions grouped together without a folder.
#       - type: fieldset
#         entity: server
#         title: 'Server: {{ server.hostname }}'
#         contents:
#           # By default OliveTin will look for an action with a matching title
#           # and put it on the dashboard.
#           #
#           # Fieldsets  also support `type: display`, which can display arbitary
#           # text. This is useful for displaying things like a container's state.
#           - type: display
#             title: |
#               Hostname: <strong>{{ server.name }}</strong>
#               IP Address: <strong>{{ server.ip }}</strong>
#
#           # These are the actions (defined above) that we want on the dashboard.
#           - title: '{{ server.name }} Wake on Lan'
#           - title: '{{ server.name }} Power Off'
#
#   # This is the second dashboard.
#   - title: My Containers
#     contents:
#       - title: 'Container {{ container.Names }} ({{ container.Image }})'
#         entity: container
#         type: fieldset
#         contents:
#           - type: display
#             title: |
#               {{ container.RunningFor }} <br /><br /><strong>{{ container.State }}</strong>
#
#           - title: 'Start {{ container.Names }}'
#           - title: 'Stop {{ container.Names }}'

OliveTin logs

olivetin  | level="info" msg="Action finding by title" actionTitle=""
olivetin  | level="warning" msg="Action requested, but not found" actionTitle=""

Screenshot of WebDeveloper console logs

N/A

Anything else?

Running the command from the APU
The command I'm running to send the request:
curl <REDACTED>/api/StartAction -X POST -d '{ "actionId": "updateContainers", "arguments": [{ "name": "hostname", "value": "<REDACTED>" }] }'

It seems to work intermittently. For example last night it was working as expected, but this morning the error occurred again.

@jamesread
Copy link
Collaborator

Hey @nickconway , very odd that this is working intermittently.

What API method are you using, /StartAction?

@nickconway
Copy link
Author

Hey @nickconway , very odd that this is working intermittently.

What API method are you using, /StartAction?

Yup, I'm using StartAction. I've got it working now after running the command from the web UI before making the request. Maybe the action id isn't being set correctly on startup?

@jamesread
Copy link
Collaborator

jamesread commented May 4, 2024

@nickconway , Ah, yep, you've found a bug! That was a good hint about refreshing the web interface seems to fix it.

OliveTin internally now uses a "public action map" that allows for virtual actions, this was added several months ago when entities were first added. That "public action map" is actually only built when /GetDashboardComponents is called (and that is called by the web interface when it first loads).

Thanks for reporting this, the fix is incredibly easy - just build that "public action map" when the API starts up, but I want to improve the unit tests in this area to make sure this doesn't come back again. Working on it right now, thanks again for reporting, will update you soon.

In the meantime, a workaround is to refresh the web interface at least once if OliveTin restarts.

@jamesread jamesread added type: bug Something isn't working progress: code-started labels May 4, 2024
@tuxthepenguin84
Copy link

I've run into this issue today, as pointed out by my wife when she said "I can't disable pihole, the button doesn't work." By button it's an iOS Shortcut/Action that does a POST to the API with /StartAction.

And running the command from the Olivetin WebUI after starting the Docker container seems to get everything fixed and working again.

Olivetin Docker Container version: 2024.04.021

Here's some logs:

level="info" msg="Action finding by title" actionTitle=""
level="warning" msg="Action requested, but not found" actionTitle=""
level="info" msg="Action finding by title" actionTitle=""
level="warning" msg="Action requested, but not found" actionTitle=""
level="info" msg="Action finding by title" actionTitle=""
level="warning" msg="Action requested, but not found" actionTitle=""
level="info" msg="Action finding by title" actionTitle=""
level="warning" msg="Action requested, but not found" actionTitle=""
level="info" msg="Action requested" actionTitle="Pi-hole Disable 5 Min" tags="[]"
level="info" msg="Action parse args - Before" actionTitle="Pi-hole Disable 5 Min" cmd="ssh olivetin@redacted_domain 'sudo salt-call event.send salt/beacon/pihole/event/disable time=\\\"5\\\"'"
level="info" msg="Action parse args - After" actionTitle="Pi-hole Disable 5 Min" cmd="ssh olivetin@redacted_domain 'sudo salt-call event.send salt/beacon/pihole/event/disable time=\\\"5\\\"'"
level="info" msg="Action starting" actionTitle="Pi-hole Disable 5 Min" timeout="5"
level="info" msg="Action finished" actionTitle="Pi-hole Disable 5 Min" exit="0" stderr="" stdout="local:\n    True\n" timedOut="false"
level="info" msg="Action requested" actionTitle="Pi-hole Disable 5 Min" tags="[]"
level="info" msg="Action parse args - Before" actionTitle="Pi-hole Disable 5 Min" cmd="ssh olivetin@redacted_domain 'sudo salt-call event.send salt/beacon/pihole/event/disable time=\\\"5\\\"'"
level="info" msg="Action parse args - After" actionTitle="Pi-hole Disable 5 Min" cmd="ssh olivetin@redacted_domain 'sudo salt-call event.send salt/beacon/pihole/event/disable time=\\\"5\\\"'"
level="info" msg="Action starting" actionTitle="Pi-hole Disable 5 Min" timeout="5"
level="info" msg="Action finished" actionTitle="Pi-hole Disable 5 Min" exit="0" stderr="" stdout="local:\n    True\n" timedOut="false"
level="info" msg="Action requested" actionTitle="Pi-hole Disable 5 Min" tags="[]"
level="info" msg="Action parse args - Before" actionTitle="Pi-hole Disable 5 Min" cmd="ssh olivetin@redacted_domain 'sudo salt-call event.send salt/beacon/pihole/event/disable time=\\\"5\\\"'"
level="info" msg="Action parse args - After" actionTitle="Pi-hole Disable 5 Min" cmd="ssh olivetin@redacted_domain 'sudo salt-call event.send salt/beacon/pihole/event/disable time=\\\"5\\\"'"
level="info" msg="Action starting" actionTitle="Pi-hole Disable 5 Min" timeout="5"
level="info" msg="Action finished" actionTitle="Pi-hole Disable 5 Min" exit="0" stderr="" stdout="local:\n    True\n" timedOut="false"

Config:

logLevel: "INFO"
showFooter: false
showNavigation: false
showNewVersions: false
checkForUpdates: false
PageTitle: "Pihole"
actions:
  - title: Pi-hole Disable 5 Min
    id: pihole5
    icon: '<img src = "customIcons/switch-off.png" width = "48px" />'
    shell: ssh olivetin@redacted_domain 'sudo salt-call event.send salt/beacon/pihole/event/disable time=\"5\"'
    timeout: 5

  - title: Pi-hole Disable Custom
    id: piholeCustom
    icon: '<img src = "customIcons/switch-off.png" width = "48px" />'
    shell: ssh olivetin@redacted_domain 'sudo salt-call event.send salt/beacon/pihole/event/disable time=\"{{ time }}\"'
    timeout: 5
    arguments:
      - name: time
        choices:
          - title: 5 Minutes
            value: 5

          - title: 15 Minutes
            value: 15

          - title: 60 Minutes
            value: 60

  - title: Pi-hole Enable
    id: piholeEnable
    icon: '<img src = "customIcons/switch-on.png" width = "48px" />'
    shell: ssh olivetin@redacted_domain 'sudo salt-call event.send salt/beacon/pihole/event/enable'
    timeout: 5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

3 participants