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

[Bug] Dasherr No Longer Communications with Glances as of Glances 4.x #24

Open
LeeThompson opened this issue May 24, 2024 · 19 comments
Open

Comments

@LeeThompson
Copy link

LeeThompson commented May 24, 2024

Glances API changed and they've dropped support for the older API formats.

Unfortunately since many users may still be running Glances 3.x, there will probably need to be alternate code paths.

I'm running Glances 4.0.4 here and Dasherr just show blank entries now. Fortunately, it's not urgent for me.

If need be I can run test code on my Dasherr install.

(The widget configuration should probably have an api version setting?)


Did some initial poking around as shown below.
Sadly my JavaScript is very iffy so I'm not able to make code suggestions.

I did try to change:
$.getJSON({url: gSettings.widgets[nW].settings.url + 'api/3/quicklook'}).done(function (result, status, xhr) {
to
$.getJSON({url: gSettings.widgets[nW].settings.url + 'api/4/quicklook'}).done(function (result, status, xhr) {
etc but it didn't do anything useful.

One interesting thing is FIrefox showed this in the console:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://redacted:61208/api/4/quicklook. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 200.

More information at Mozilla Reference

http://redacted:61208/api/4/sensors

[
  {
    "label": "adt7490 0",
    "unit": "C",
    "value": 28,
    "warning": 127,
    "critical": 100,
    "type": "SensorType.CPU_TEMP",
    "key": "label"
  },
  {
    "label": "adt7490 1",
    "unit": "C",
    "value": 32,
    "warning": 127,
    "critical": 100,
    "type": "SensorType.CPU_TEMP",
    "key": "label"
  },
  {
    "label": "adt7490 2",
    "unit": "C",
    "value": 36,
    "warning": 127,
    "critical": 100,
    "type": "SensorType.CPU_TEMP",
    "key": "label"
  },
  {
    "label": "k10temp 0",
    "unit": "C",
    "value": 35,
    "warning": 70,
    "critical": 70,
    "type": "SensorType.CPU_TEMP",
    "key": "label"
  },
  {
    "label": "adt7490 0",
    "unit": "R",
    "value": 1817,
    "warning": null,
    "critical": null,
    "type": "SensorType.FAN_SPEED",
    "key": "label"
  },
  {
    "label": "adt7490 1",
    "unit": "R",
    "value": 1844,
    "warning": null,
    "critical": null,
    "type": "SensorType.FAN_SPEED",
    "key": "label"
  },
  {
    "label": "adt7490 2",
    "unit": "R",
    "value": 0,
    "warning": null,
    "critical": null,
    "type": "SensorType.FAN_SPEED",
    "key": "label"
  },
  {
    "label": "adt7490 3",
    "unit": "R",
    "value": 0,
    "warning": null,
    "critical": null,
    "type": "SensorType.FAN_SPEED",
    "key": "label"
  }
]

http://redacted:61208/api/4/quicklook

{
  "cpu_name": "AMD Ryzen Embedded V1500B",
  "cpu_hz_current": 2200000000,
  "cpu_hz": 2200000000,
  "cpu": 1.7,
  "percpu": [
    {
      "key": "cpu_number",
      "cpu_number": 0,
      "total": 2.5,
      "user": 1.5,
      "system": 0.6,
      "idle": 97.5,
      "nice": 0,
      "iowait": 0.5,
      "irq": 0,
      "softirq": 0,
      "steal": 0,
      "guest": 0,
      "guest_nice": 0
    },
    {
      "key": "cpu_number",
      "cpu_number": 1,
      "total": 1.1,
      "user": 0.9,
      "system": 0.2,
      "idle": 98.9,
      "nice": 0,
      "iowait": 0,
      "irq": 0,
      "softirq": 0,
      "steal": 0,
      "guest": 0,
      "guest_nice": 0
    },
    {
      "key": "cpu_number",
      "cpu_number": 2,
      "total": 2,
      "user": 1.2,
      "system": 0.5,
      "idle": 98,
      "nice": 0,
      "iowait": 0.4,
      "irq": 0,
      "softirq": 0,
      "steal": 0,
      "guest": 0,
      "guest_nice": 0
    },
    {
      "key": "cpu_number",
      "cpu_number": 3,
      "total": 0.9,
      "user": 0.7,
      "system": 0.2,
      "idle": 99.1,
      "nice": 0,
      "iowait": 0,
      "irq": 0,
      "softirq": 0,
      "steal": 0,
      "guest": 0,
      "guest_nice": 0
    },
    {
      "key": "cpu_number",
      "cpu_number": 4,
      "total": 2.8,
      "user": 1.9,
      "system": 1,
      "idle": 97.2,
      "nice": 0,
      "iowait": 0,
      "irq": 0,
      "softirq": 0,
      "steal": 0,
      "guest": 0,
      "guest_nice": 0
    },
    {
      "key": "cpu_number",
      "cpu_number": 5,
      "total": 1,
      "user": 0.6,
      "system": 0.4,
      "idle": 99,
      "nice": 0,
      "iowait": 0,
      "irq": 0,
      "softirq": 0,
      "steal": 0,
      "guest": 0,
      "guest_nice": 0
    },
    {
      "key": "cpu_number",
      "cpu_number": 6,
      "total": 2.7,
      "user": 1.5,
      "system": 0.8,
      "idle": 97.3,
      "nice": 0,
      "iowait": 0.5,
      "irq": 0,
      "softirq": 0,
      "steal": 0,
      "guest": 0,
      "guest_nice": 0
    },
    {
      "key": "cpu_number",
      "cpu_number": 7,
      "total": 0.8,
      "user": 0.6,
      "system": 0.2,
      "idle": 99.2,
      "nice": 0,
      "iowait": 0,
      "irq": 0,
      "softirq": 0,
      "steal": 0,
      "guest": 0,
      "guest_nice": 0
    }
  ],
  "mem": 31.3,
  "swap": 11,
  "cpu_log_core": 8,
  "cpu_phys_core": 4,
  "load": 3.4
}

http://redacted:61208/api/3/quicklook

{
  "detail": "Not Found"
}
@LeeThompson
Copy link
Author

LeeThompson commented May 26, 2024

UPDATE: There is something going on with the CORS policy that seems to be new. Did Glances prior to v3 set CORS headers?

I worked around this by changing the API version from v3 to v4 and enabled CORS on Traefik and seem to have this working again.

Not sure what the proper solution is.

Workaround

Traefik

https://doc.traefik.io/traefik/middlewares/http/headers/

I use staticfile for my environment so I made these changes in staticconfig.yml:

In the middlewares: section.

    testHeader:
      headers:
        accessControlAllowMethods:
          - GET
          - OPTIONS
          - PUT
        accessControlAllowHeaders: "*"
        accessControlAllowOriginList: "*"
        accessControlMaxAge: 100
        addVaryHeader: false

I have 3 machines that run glances, so I have it set up in Traefik so each one can be accessed like http://glances.local/docker1/ http://glances.local/docker2/ etc.

Under services: section:

    glancesdocker1:
      loadBalancer:
        servers:
          - url: http://docker1.local:61208/

Under the routers section is where the CORS configuration comes in.

    glances_docker1
      entryPoints:
        - http
      rule: "Host(`glances.local`) && PathPrefix(`/docker1`)"
      middlewares:
        - testHeader
      service: glancesdocker1

Dasherr

The include\worker.js needs changed:
Basically the api/v3 needs changed to api/v4.

Presumably you could also do this in Traefik but I think this is easier.

function refreshWidgetGlances(nW) {
    $.getJSON({url: gSettings.widgets[nW].settings.url + 'api/4/quicklook'}).done(function (result, status, xhr) {   
		document.getElementById('cpuPrct' + nW).innerText = result.cpu + '%'
		document.getElementById('memPrct' + nW).innerText = result.mem + '%'
	});
	
    $.getJSON({url: gSettings.widgets[nW].settings.url + 'api/4/sensors'}).done(function (result, status, xhr) {
		document.getElementById('cpuTemp' + nW).innerText = (result.length > 0? result[0].value + 'C' : '-')
	});
}

Of course in the various settings pages, in the widget section the URLs will need to be updated to http://glances.local/docker1/ and so on.

@erohtar
Copy link
Owner

erohtar commented May 27, 2024

Thank you for all the detailed information and finding the workaround in the meantime. And you're right in solving it by tweaking Traefik - while I have never used it myself, since it's a proxy + api gateway, that's where I'd look for the solution too.

I personally almost never get any CORS related issues as I run everything under a closed Tailscale network on limited devices - which I understand isn't everyone's use case.

API deprecation: While I'd pulled fresh docker images of my docker apps recently, I didn't realize I was running an older version of Glances since they stopped supporting 32-bit images a while back, and my Raspberry Pi is still running on a 32-bit OS. I guess I'll have to take backups, and recreate everything from a fresh OS install, to fix this one and install latest version of Glances (and few other containers that have the same story). Once I'm on the latest version, I should be able to face (and fix) this problem.

@erohtar
Copy link
Owner

erohtar commented May 27, 2024

Well, guess what - I had a few hours free today and your push made me go ahead with the Pi rebuild to make it 64-bit.

Now I can see the latest Glances provides the correct data on /4/ instead of /3/ and somehow I'm getting the CORS error too. I've updated the worker.js to your recommended change already, but haven't created another release yet - I want to see if there's an easier way to resolve the CORS problem.

@LeeThompson
Copy link
Author

I don't really know the CORS system very well, other than vague concepts, unfortunately.

I'm having a discussion with the Glances maintainer but I'm probably coming across like an idiot :)

@erohtar
Copy link
Owner

erohtar commented May 27, 2024

Per my understanding, that bind option will go in your docker compose right after the default '-w' option. They already clarified that the code block is part of Glances already, so nothing to worry about there.

@LeeThompson
Copy link
Author

I'm not sure why the bind option is necessary (also Docker containers don't have static IP addresses).

@erohtar
Copy link
Owner

erohtar commented May 27, 2024

Yeah I'm not sure either on how exactly would that binding resolve the problem, but that's where I'd try it.

And I don't think you need the container's ip address, just of the machine that is going to access Glances (the one running Dasherr)

(I'm just about to go to bed, but I'll definitely be trying this tomorrow, though I'm sure you'll beat me to it)

@LeeThompson
Copy link
Author

I tried adding this to one of my Glances instances:
GLANCES_OPT -w --bind nas02.redacted

The redacted bind is the exact intranet fully qualified domain name that Dasherr uses and I get the same CORS error.

@LeeThompson
Copy link
Author

LeeThompson commented May 27, 2024

I tried binding with the web server (where Dasherr) runs, but that causes the container to stop with a fatal error :)

@LeeThompson
Copy link
Author

I'm not sure how helpful any of this is, but I noticed some things:

When Dasherr is getting Glances data via Traefik, the response header looks like:

HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Content-Length: 885
Content-Type: application/json
Date: Tue, 28 May 2024 08:10:05 GMT
Server: uvicorn

When it's talking to Glances directly it looks like:

HTTP/1.1 200 OK
date: Tue, 28 May 2024 08:11:39 GMT
server: uvicorn
content-length: 367
content-type: application/json
access-control-allow-credentials: true
content-encoding: gzip
vary: Accept-Encoding

The CORS access control is not present.

@erohtar
Copy link
Owner

erohtar commented May 28, 2024

So I've been trying a few things today and I met with the same findings/results as you did (no surprise there really).

I'm no expert on CORS so something that I found out very recently may just be common knowledge, but what I learnt is that two services running on the same domain/url but on different ports are NOT considered to be the same origin! That might make some sense from security POV, but didn't make much sense to me from the intuitive POV.

Also, it appears that the allow_origins=[self.bind_url] part of Glances code is the problem, as it is set to only allow its own url (which means same domain AND same port) to access the API - and so far I'm not sure how to work around that from the client-end.

@LeeThompson
Copy link
Author

It looks like Glances is being updated to default to allow_origins=* (I already tested the change and it works like it should).

You might want to have Dasherr's widget section specify which api version to use since some folks may be sticking with Glances v3.

Whee

@erohtar
Copy link
Owner

erohtar commented May 30, 2024

Thank you so much for championing the cause! I tested the dev version and it works great.

You might want to have Dasherr's widget section specify which api version to use

I feel that might not be needed. The only real reason to use the older version is if one is on 32-bit OS (like I recently was), and for them Glances wouldn't even update to the new version. Now the only edge-case scenario I can think of is if someone like that updates to latest Dasherr but not latest Glances, but at least the next Dasherr update would be of no use to them.

@LeeThompson
Copy link
Author

LeeThompson commented Jun 4, 2024

It looks like the change (nicolargo/glances#2812) is targeted for Glances 4.1.0 (https://github.com/nicolargo/glances/milestone/68?closed=1)

The downside is the release target for 4.1.0 is September 1st.

So current Dasherr users with this issue can (in order of less work on Dasherr side)

  1. Run Glances' "dev' branch
  2. Downgrade to Glances 3.x
  3. Disable the widget in Dasherr for now
  4. Use Traefik or some other proxy to force the correct CORS options (and change the Dasherr settings appropriately)

@erohtar
Copy link
Owner

erohtar commented Jun 4, 2024

Got it. I've also been intermittently checking if a new stable docker image has been released for Glances, and since there wasn't one, I waited.

@LeeThompson
Copy link
Author

Looks like it got released with 4.0.8 actually.

@erohtar
Copy link
Owner

erohtar commented Jun 12, 2024

Oh wow, you're right - I just ran it with the 'latest' tag and it works as it should.
But I just noticed there's something that's not working - is the settings saving working as expected for you in the Dasherr Editor? It seems to be broken for me and before I try to figure out what/when it happened, just want to be sure it's not something that went wrong during my Pi upgrade.

@LeeThompson
Copy link
Author

I don't use the Dasherr editor, I use notepad++ to edit the json files because I'm using a number of pages. I abuse Dasherr to use it as a menu system more than a dashboard.

@erohtar
Copy link
Owner

erohtar commented Jul 1, 2024

I'm sorry for taking this long. My plan was to look into the code editor issue and make a couple other changes I had on my mind, but being busy with other things kept me pushing this down. Finally I figured it's best to release this one and work on the rest once I get to it.
Thank you again for all the terrific help with this one.

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

No branches or pull requests

2 participants