udevbe / greenfield

HTML5 Wayland compositor :seedling:
GNU Affero General Public License v3.0
913 stars 28 forks source link

Opening the URL simply presents "Upgrade required" #85

Closed rosensvv closed 2 years ago

rosensvv commented 2 years ago

I am running my own instance using docker, proxied by traefik using the following configuration in compose:

version: '3.8'
services:
  compositor-proxy:
    build:
      context: .
      dockerfile: ./Dockerfile
    privileged: true
    volumes:
      - xdg-runtime-dir:/xdg-runtime-dir
      - x11-unix:/tmp/.X11-unix
      - ${PWD}/src/config.yaml:/app/config.yaml
    ports:
      - 8081:8081
    environment:
      GST_GL_WINDOW: gbm
      COMPOSITOR_SESSION_ID: test123
      DEBUG: 1
      GST_DEBUG: 3
      XDG_RUNTIME_DIR: /xdg-runtime-dir
      XAUTHORITY: /tmp/.X11-unix/Xauthority
  gtk3-demo:
    pid: 'service:compositor-proxy'
    build:
      context: example-apps/gtk3-demo
      dockerfile: Dockerfile
    volumes:
      - xdg-runtime-dir:/xdg-runtime-dir
    environment:
      XDG_RUNTIME_DIR: /xdg-runtime-dir
    restart: always
  xterm:
    pid: 'service:compositor-proxy'
    build:
      context: example-apps/xterm
      dockerfile: Dockerfile
    privileged: false
    volumes:
      - xdg-runtime-dir:/xdg-runtime-dir
      - x11-unix:/tmp/.X11-unix
    environment:
      XAUTHORITY: /tmp/.X11-unix/Xauthority
      XDG_RUNTIME_DIR: /xdg-runtime-dir
      DISPLAY: ':1'
    restart: always
volumes:
  xdg-runtime-dir:
    driver_opts:
      type: tmpfs
      device: tmpfs
  x11-unix:
    driver_opts:
      type: tmpfs
      device: tmpfs

When I open the service in a browser, it simply gives a string "update required". Unrelated, I couldn't understand where to install additional GUI apps to be used by the compositor, is that supposed to be a separate container?

rosensvv commented 2 years ago

Here is the log from the compositor container:

Reading configuration from: /app/config.yaml
[1637320145281] INFO (main/11 on 91f4a9bf1635): Starting compositor proxy...
[1637320145284] INFO (native-compositor-session/11 on 91f4a9bf1635): Listening on: WAYLAND_DISPLAY="wayland-0".
xserver listening on display :1
[1637320145285] INFO (compositor-proxy-session/11 on 91f4a9bf1635): Session created.
[1637320145288] INFO (main/11 on 91f4a9bf1635): Compositor proxy started. Listening on port 8081
[1637320147335] INFO (native-compositor-session/11 on 91f4a9bf1635): New Wayland connection.
[1637320147335] DEBUG (native-compositor-session/11 on 91f4a9bf1635): No client found without a wayland connection, will create a placeholder client without a websocket connection.
[1637320147351] DEBUG (native-client-session/11 on 91f4a9bf1635): Received messages from client, will delegate. Size: 12, object-id: 1, opcode: 1
[1637320147352] DEBUG (native-client-session/11 on 91f4a9bf1635): Message from client delegated to browser and native.
[1637320147353] DEBUG (native-client-session/11 on 91f4a9bf1635): Received messages from client, will delegate. Size: 12, object-id: 1, opcode: 0
[1637320147354] DEBUG (native-client-session/11 on 91f4a9bf1635): Message from client delegated to browser
[1637320147354] DEBUG (native-client-session/11 on 91f4a9bf1635): Received end of client message.
[1637320147354] DEBUG (native-client-session/11 on 91f4a9bf1635): Client message queued because websocket is not open.
[1637320147503] INFO (native-compositor-session/11 on 91f4a9bf1635): New Wayland connection.
[1637320147503] DEBUG (native-compositor-session/11 on 91f4a9bf1635): No client found without a wayland connection, will create a placeholder client without a websocket connection.
Spawned Xwayland server, pid 37
[1637320147523] DEBUG (native-client-session/11 on 91f4a9bf1635): Received messages from client, will delegate. Size: 12, object-id: 1, opcode: 1
[1637320147524] DEBUG (native-client-session/11 on 91f4a9bf1635): Message from client delegated to browser and native.
[1637320147524] DEBUG (native-client-session/11 on 91f4a9bf1635): Received messages from client, will delegate. Size: 12, object-id: 1, opcode: 0
[1637320147524] DEBUG (native-client-session/11 on 91f4a9bf1635): Message from client delegated to browser
[1637320147524] DEBUG (native-client-session/11 on 91f4a9bf1635): Received end of client message.
[1637320147524] DEBUG (native-client-session/11 on 91f4a9bf1635): Client message queued because websocket is not open.
Zubnix commented 2 years ago

It looks like your browser can't make a websocket connection to the compositor-proxy. Have you tried confirming if proxying websocket connections works with traefik independently?

"Unrelated, I couldn't understand where to install additional GUI apps to be used by the compositor, is that supposed to be a separate container?"

Indeed, you could add a new entry like the xterm or gtk3-demo. Keep in mind though, this docker-compose is mostly for demo purpose but you are ofcourse free to use it as you like. The main purpose of Greenfield is to offer a way to proxy Wayland apps to your browser, how you manage your applications is up to you.

rosensvv commented 2 years ago

Reading online, it seems that traefik should just proxy websockets without issue. As a test, I tried opening the URL directly without a proxy and it behaves the same way. Is there something I'm missing here?

Zubnix commented 2 years ago

The compositor-proxy is just a simple websocket server, nothing special. You can try using a program like wscat to test the connection. You should see some binary garbage if you're connected and a Wayland client connects to the compositor-proxy.

You can first try on the same machine as where the compositor-proxy docker compose is running and if working you can try connecting from a remote machine. I'm not a docker specialist but maybe docker-compose doesn't allow incoming external network requests by default?

rosensvv commented 2 years ago

I tried using websocat and it simply connects without outputting anything. I cannot do it on the local machine as this is a headless server that is in a datacenter. I'm assuming I can't get a wayland client connected as I would need to connect using my browser?

Zubnix commented 2 years ago

OK I finally understand your issue (I managed to reproduce it).

You can't simply go to 'http://localhost:8081' using the docker-compose. The docker-compose file only hosts the compositor-proxy (hence why it's in the compositor-proxy directory), and does not provide, say an nginx with the static site resources required to display everything in your browser.

What's happening is that you are using an http connection to connect to a websocket server so you are greeted with 'upgrade required'.

What you need to do is run the compositor-module demo in order to quickly test your setup, as mentioned in the README.md

The Greenfield Compositor Module comes with a very simple demo compositor implementation that you can use. Inside compositor-module directory run.

However The demo compositor is configured to connect to a compositor-proxy on localhost, you can easily change that here: https://github.com/udevbe/greenfield/blob/e7022e5742806aa61ac47490dd022351493f556f/compositor-module/demo-compositor/src/index.ts#L34

I'll see if I can update the README to make this more clear.

ps. I just updated the encoding pipeline on master so you might want to update your sources & rebuild your docker-compose containers ie docker-compose down && docker-compose build --pull && docker-compose up

rosensvv commented 2 years ago

Thank you for the clarification. Unfortunately, it still seems to not be working, I get Firefox can’t establish a connection to the server at ws://*myiphere*:8081/?compositorSessionId=test123. , despite clearly getting "upgrade required" when i type in that same URL into the browser address field (I also tried with localhost on the server running the compositor-proxy). Additionally, can this compositor-module be on the local machine that also hosts the compositor-proxy or is it necessary (for performance or otherwise) to be run on the remote machine? Can I make a docker container and add it to the other docker-compose to have the whole thing running remotely with only the browser running on the client? Lastly, is it possible to have the compositor-module auto connect to a predefined websockets endpoint?

Zubnix commented 2 years ago

Hi, could you by any change show me short video or screenshot of the error you are getting? I'm having a hard time to identify the failure cause. Did you manage to run the whole setup locally?

To answer your other question. The compositor-module can be hosted anywhere you want. It's just a static html page with static javascript. Since it uses websocket to connect to the compositor-proxy, you're event exempt of any CORS errors.

rosensvv commented 2 years ago

I wish I could provide more useful information but I don't know where to look for it. Anyway, here is a screenshot of the error message I'm receiving in Firefox (the same happens in Chrome). I tried both running the module locally and on the server - same result.... Another thing to note: when I attempt to connect via websocat I (expectedly) get "Bad or missing compositorSessionId query parameter." in the compositor-proxy log, but when I'm connecting through the compositor module, I see nothing new in the server logs - maybe it's not even reaching it for some reason.... screenshot-2021-11-23-10:01:23 ..

Zubnix commented 2 years ago

It gives you error code 1015 see: https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/code

 Indicates that the connection was closed due to a failure to perform a TLS handshake (e.g., the server certificate can't be verified).

Are you mixing secure and insecure environments or something alike?

rosensvv commented 2 years ago

Do I need HTTPS? I am simply following your instructions: brought up the docker-compose for the compositor-proxy, then started the compositor-module using yarn demo, setting the websockets URL in that index.ts file. Everything should be unencrypted. Another thing to note is that this error is only when the compositor-module is run on the thin client, if it runs on the server the error code is 1006 Indicates that a connection was closed abnormally (that is, with no close frame being sent) when a status code is expected. Could be my server though, as yarn complained about being too old (I can't upgrade the host environment at the moment) Also, if I try to proxy the module using traefik/https it just says invalid host header (because I'm using my domain name to connect to it) and I don't know how to make it accept that. But wouldn't that also be mixing secure and insecure environments, as I would need secure websockets (wss)?

Zubnix commented 2 years ago

Do I need HTTPS? I am simply following your instructions: brought up the docker-compose for the compositor-proxy, then started the compositor-module using yarn demo, setting the websockets URL in that index.ts file. Everything should be unencrypted.

No, there are no assumptions about https or wss in Greenfield. Everything is unencrypted by default. The idea is that if you need encryption, you can setup your own SSL termination through a reverse proxy.

Another thing to note is that this error is only when the compositor-module is run on the thin client.

That's really odd, it looks like for some reason the browser is doing/performing a (failed) TLS check.

If it runs on the server the error code is 1006 Indicates that a connection was closed abnormally (that is, with no close frame being sent) when a status code is expected. Could be my server though, as yarn complained about being too old (I can't upgrade the host environment at the moment)

That usually happens when the connection was terminated because the program (compositor-proxy in thise case) stopped/crashed/errored.

Also, if I try to proxy the module using traefik/https it just says invalid host header (because I'm using my domain name to connect to it) and I don't know how to make it accept that. But wouldn't that also be mixing secure and insecure environments, as I would need secure websockets (wss)?

Yes, you can't connect using ws while your site is running on a secure https domain. I do believe you can get webpack to use any domain. The compositor-module demo uses webpack 5, google + stack overflow should give some answers on how to do that.

rosensvv commented 2 years ago

So in that case something must be wrong with compositor-proxy, not compositor-module? I could try running it natively instead of using docker but I was worried my host is a bit outdated and will cause a dependency mess. Given that I can't see any errors in the log regarding the 1006 code, should I be looking elsewhere for a solution? I'm not gonna bother with https for now but I have no idea on what else I can do. Is the docker-compose file working for you or is it something old and unmaintained?

Zubnix commented 2 years ago

It's maintained and should work. I've made a short screencast starting from a fresh git clone: https://youtu.be/SiVfCMqpj3Q

I'm honestly out of ideas why your setup is not working out. 😞

rosensvv commented 2 years ago

Okay, I did a clean install on a fresh new machine exactly following your video and it appears to be working now. I have to say, this is an amazing piece of software, even in this early state, thank you for the great work you did and for the help. I am going to submit a pull request with more detailed documentation and a more polished, easy to setup docker-compose (I will see if I can set up variables for things like canvas size and potentially even https for easy proxying). You are the best, keep up the good work!