glances icon indicating copy to clipboard operation
glances copied to clipboard

url_prefix does not work on develop

Open GeorgeA93 opened this issue 1 year ago • 1 comments

Describe the bug

url_prefix option is no longer working on develop, believe this is due to the recent switch to FastAPI.

Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "/app/glances/__main__.py", line 18, in <module>
    glances.main()
  File "/app/glances/__init__.py", line 184, in main
    start(config=core.get_config(), args=core.get_args())
  File "/app/glances/__init__.py", line 107, in start
    mode = GlancesMode(config=config, args=args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/glances/webserver.py", line 34, in __init__
    self.web = GlancesRestfulApi(config=config, args=args)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/glances/outputs/glances_restful_api.py", line 88, in __init__
    self._app.include_router(APIRouter(prefix=self.url_prefix))
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/venv/lib/python3.11/site-packages/fastapi/routing.py", line 809, in __init__
    assert not prefix.endswith(
AssertionError: A path prefix must not end with '/', as the routes will start with '/'

To Reproduce Steps to reproduce the behavior:

  1. Start Glances with the following options 'url_prefix=/glances/'
  2. Look at logs
  3. See error

Expected behavior The app should launch with the correct url_prefix

GeorgeA93 avatar Feb 12 '24 18:02 GeorgeA93

Patch done on the develop branch.

Can you test it @GeorgeA93 ?

Thanks !

nicolargo avatar Feb 17 '24 10:02 nicolargo

@GeorgeA93 any feedback ?

nicolargo avatar Mar 04 '24 08:03 nicolargo

This appears to still not be working... I've got it reading my glances.conf file, I'm able to change other options but when putting in a url_prefix of /glances/ it doesn't honor it.

stevenmcastano avatar Jul 13 '24 19:07 stevenmcastano

I'm experiencing the same. Using docker.

I've copied the glances.conf that is referenced by the documentation, and placed that in my persistent data folder (see docker compose below for reference). The only change I've made int the config is uncommenting url_prefix=/glances/.

I've enabled debug logging and added the glances.json as per the documentation, only changing the path for the logfile to "filename": "/var/log/glances.log".

glances.log

2024-08-03 19:11:15,924 -- INFO -- Start Glances 4.1.2
2024-08-03 19:11:15,924 -- INFO -- CPython 3.11.9 (/venv/bin/python3) and psutil 6.0.0 detected
2024-08-03 19:11:15,929 -- INFO -- Read configuration file '/glances/glances.conf'
...
2024-08-03 19:11:16,508 -- INFO -- Start GlancesWebServer mode
...
2024-08-03 19:11:16,695 -- DEBUG -- Trying paths: ['/root/.docker/config.json', '/root/.dockercfg']
2024-08-03 19:11:16,695 -- DEBUG -- No config file found
2024-08-03 19:11:16,695 -- DEBUG -- Trying paths: ['/root/.docker/config.json', '/root/.dockercfg']
2024-08-03 19:11:16,695 -- DEBUG -- No config file found
...
2024-08-03 19:11:16,928 -- DEBUG -- URL prefix: /glances/
2024-08-03 19:11:16,941 -- INFO -- Glances RESTful API Server started on http://0.0.0.0:61208/glances/api/4
2024-08-03 19:11:16,942 -- INFO -- Get WebUI in /app/glances/outputs/static/public
2024-08-03 19:11:16,942 -- INFO -- Glances Web User Interface started on http://0.0.0.0:61208/glances/
2024-08-03 19:11:16,952 -- DEBUG -- Glances started in 1.02236 seconds
...
2024-08-03 19:12:26,567 -- DEBUG -- Debug file (/tmp/glances-debug.json) not found
...

docker logs --follow glances

2024-08-03T19:04:16.971987557Z INFO:     Started server process [41784]
2024-08-03T19:04:16.972164371Z INFO:     Waiting for application startup.
2024-08-03T19:04:16.972447529Z INFO:     Application startup complete.
2024-08-03T19:04:16.972894330Z INFO:     Uvicorn running on http://0.0.0.0:61208 (Press CTRL+C to quit)
2024-08-03T19:12:27.435191716Z Glances Web User Interface started on http://0.0.0.0:61208/glances/
2024-08-03T19:12:27.435212669Z INFO:     172.18.0.2:59626 - "GET /glances/ HTTP/1.1" 404 Not Found
2024-08-03T19:27:23.404963205Z WARNING:  Invalid HTTP request received.
2024-08-03T19:27:23.406552859Z WARNING:  Invalid HTTP request received.
2024-08-03T19:27:23.521531270Z INFO:     192.168.1.123:54993 - "GET /?refresh=60 HTTP/1.1" 200 OK
2024-08-03T19:27:23.606368177Z INFO:     192.168.1.123:54993 - "GET /api/4/all HTTP/1.1" 200 OK
2024-08-03T19:27:23.609305626Z INFO:     192.168.1.123:54994 - "GET /api/4/all/views HTTP/1.1" 200 OK
2024-08-03T19:27:23.610666948Z INFO:     192.168.1.123:54995 - "GET /api/4/all/limits HTTP/1.1" 200 OK
2024-08-03T19:27:23.611213084Z INFO:     192.168.1.123:54997 - "GET /api/4/config HTTP/1.1" 200 OK
2024-08-03T19:27:23.611798653Z INFO:     192.168.1.123:54996 - "GET /api/4/args HTTP/1.1" 200 OK
2024-08-03T19:28:23.679419123Z INFO:     192.168.1.123:55056 - "GET /api/4/all/views HTTP/1.1" 200 OK
2024-08-03T19:28:23.780119222Z INFO:     192.168.1.123:55055 - "GET /api/4/all HTTP/1.1" 200 OK
2024-08-03T19:28:40.303956894Z WARNING:  Invalid HTTP request received.
2024-08-03T19:28:40.305494265Z WARNING:  Invalid HTTP request received.
2024-08-03T19:28:40.310573465Z INFO:     192.168.1.123:55073 - "GET /glances/?refresh=60 HTTP/1.1" 404 Not Found

Requests from 192.168.1.123 are connections directly to the published docker port, i.e. not through Traefik. Requests from 172.18.0.2 are through Traefik. This was to show that it doesn't matter if connecting directly to http://glances-host:61208/glances/ or through https://traefik-proxy/glances/.

docker-compose.yaml

networks:
  proxy:
    external: true

services:
  glances:
    image: nicolargo/glances:latest
    container_name: glances
    hostname: ${CONTAINER_HOSTNAME:-${HOSTNAME}}
    pid: host
    restart: unless-stopped
    environment:
      - TZ=UTC
      - GLANCES_OPT=--webserver --config /glances/glances.conf --debug
      - LOG_CFG=/glances/glances.json
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /opt/glances/glances.conf:/glances/glances.conf:ro
      - /opt/glances/glances.json:/glances/glances.json:ro
      - /var/log/glances.log:/var/log/glances.log:rw
    ports:
      - 61208:61208
    networks:
      proxy:
    labels:
      - traefik.enable=true
      - traefik.docker.network=proxy
      - traefik.http.services.svc-glances.loadBalancer.server.scheme=http
      - traefik.http.services.svc-glances.loadBalancer.server.port=61208
      - traefik.http.middlewares.mdw-redirect-glances.redirectRegex.regex=^(https://[^/]+/glances)([^/].)?$
      - traefik.http.middlewares.mdw-redirect-glances.redirectRegex.replacement=$${1}/$${2}
      - traefik.http.routers.rtr-glances.middlewares=mdw-redirect-glances
      - traefik.http.routers.rtr-glances.service=svc-glances
      - traefik.http.routers.rtr-glances.entryPoints=https
      - traefik.http.routers.rtr-glances.rule=Host(`${TRAEFIK_SUBJECT_CN}`) && PathPrefix(`/glances`)

I did manage to implement a workaround using Traefik stripPrefix Middleware, but /glances/docs#/ would still return a 404 because it was attempting to fetch the openapi.json from the root path /. I did find a workaround for that as well, here.

Here's the working (workaround) docker-compose.yaml.

docker-compose.yaml

networks:
  proxy:
    external: true

services:
  glances:
    image: nicolargo/glances:latest
    container_name: glances
    hostname: ${CONTAINER_HOSTNAME:-${HOSTNAME}}
    pid: host
    restart: unless-stopped
    environment:
      - TZ=UTC
      - GLANCES_OPT=--webserver
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    ports:
      - 61208:61208
    networks:
      proxy:
    labels:
      - traefik.enable=true
      - traefik.docker.network=proxy
      - traefik.http.services.svc-glances.loadBalancer.server.scheme=http
      - traefik.http.services.svc-glances.loadBalancer.server.port=61208
      - traefik.http.middlewares.mdw-redirect-glances.redirectRegex.regex=^(https://[^/]+/glances)([^/].)?$
      - traefik.http.middlewares.mdw-redirect-glances.redirectRegex.replacement=$${1}/$${2}
      - traefik.http.middlewares.mdw-rmPrefix-glances.stripPrefix.prefixes=/glances
      - traefik.http.middlewares.mdw-chain-glances.chain.middlewares=mdw-redirect-glances,mdw-rmPrefix-glances
      - traefik.http.routers.rtr-glances.middlewares=mdw-chain-glances
      - traefik.http.routers.rtr-glances.service=svc-glances
      - traefik.http.routers.rtr-glances.entryPoints=https
      - traefik.http.routers.rtr-glances.rule=Host(`${TRAEFIK_SUBJECT_CN}`) && (PathPrefix(`/glances`) || HeaderRegexp(`Referer`, `.+/glances/?.*`))

briped avatar Aug 03 '24 19:08 briped