feat: Add WASM build for toxcore and websocket bootstrap node.

The websocket bootstrap node will be running on Heroku.
This commit is contained in:
iphydf 2022-02-02 13:03:01 +00:00
parent 727982d2f9
commit 71965a0f3b
No known key found for this signature in database
GPG Key ID: 3855DBA2D74403C9
11 changed files with 296 additions and 8 deletions

View File

@ -18,9 +18,9 @@ branches:
- "bazel-opt" - "bazel-opt"
- "bazel-tsan" - "bazel-tsan"
- "bazel-valgrind" - "bazel-valgrind"
- "build-bootstrapd-docker"
- "build-compcert" - "build-compcert"
- "build-macos" - "build-macos"
- "build-msan"
- "build-nacl" - "build-nacl"
- "build-tcc" - "build-tcc"
- "build-win32" - "build-win32"
@ -38,6 +38,9 @@ branches:
- "cimple" - "cimple"
- "code-review/reviewable" - "code-review/reviewable"
- "continuous-integration/appveyor/pr" - "continuous-integration/appveyor/pr"
- "docker-bootstrap-node"
- "docker-bootstrap-node-websocket"
- "docker-toxcore-js"
- "mypy" - "mypy"
- "sonar-scan" - "sonar-scan"

View File

@ -7,13 +7,11 @@ on:
branches: [master] branches: [master]
jobs: jobs:
build-bootstrapd-docker: docker-bootstrap-node:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Login to DockerHub - name: Login to DockerHub
if: github.event_name == 'push' if: ${{ github.event_name == 'push' }}
uses: docker/login-action@v1 uses: docker/login-action@v1
with: with:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
@ -22,8 +20,49 @@ jobs:
- name: Docker Build - name: Docker Build
run: .github/scripts/tox-bootstrapd-docker local run: .github/scripts/tox-bootstrapd-docker local
- name: Push latest image to DockerHub - name: Push latest image to DockerHub
if: github.event_name == 'push' if: ${{ github.event_name == 'push' }}
run: docker push toxchat/bootstrap-node:latest run: docker push toxchat/bootstrap-node:latest
- name: Push versioned image to DockerHub - name: Push versioned image to DockerHub
if: github.event_name == 'push' && contains(github.ref, 'refs/tags/') if: ${{ github.event_name == 'push' && contains(github.ref, 'refs/tags/') }}
run: docker push toxchat/bootstrap-node:"$(other/print-version)" run: docker push toxchat/bootstrap-node:"$(other/print-version)"
docker-toxcore-js:
runs-on: ubuntu-latest
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Login to DockerHub
if: ${{ github.event_name == 'push' }}
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v2
with:
file: other/emscripten/Dockerfile
push: ${{ github.event_name == 'push' }}
tags: toxchat/toxcore-js:latest
cache-from: type=registry,ref=toxchat/toxcore-js:latest
cache-to: type=inline
docker-bootstrap-node-websocket:
runs-on: ubuntu-latest
needs: [docker-bootstrap-node]
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Login to DockerHub
if: ${{ github.event_name == 'push' }}
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v2
with:
context: "{{defaultContext}}:other/bootstrap_daemon/websocket"
push: ${{ github.event_name == 'push' }}
tags: toxchat/bootstrap-node:latest-websocket
cache-from: type=registry,ref=toxchat/bootstrap-node:latest-websocket
cache-to: type=inline

View File

@ -1,5 +1,9 @@
--- ---
ignored: ignored:
# "cd" is sometimes useful when you want to run one command in one directory
# and then another command in another directory, but they should be executed
# in the same RUN instruction.
- DL3003
- DL3007 - DL3007
- DL3008 - DL3008
- DL3013 - DL3013

4
heroku.yml Normal file
View File

@ -0,0 +1,4 @@
---
build:
docker:
web: other/bootstrap_daemon/websocket/Dockerfile

View File

@ -1,4 +1,4 @@
#!/bin/sh #!/usr/bin/env bash
set -eux set -eux

View File

@ -0,0 +1,29 @@
# Stage 1 - Compile websockify.
FROM toxchat/bootstrap-node:latest AS tox
FROM golang:1.17-alpine AS websockify
COPY websockify /work/websockify
RUN cd /work/websockify && go mod download github.com/gorilla/websocket && go install
# Stage 2 - Create the run-time image with bootstrap daemon and websockify.
FROM alpine:latest
RUN addgroup -S tox && adduser -SDH -G tox tox
COPY --from=websockify /go/bin/websockify /usr/local/bin/
COPY --from=tox /usr/local /usr/local/
COPY --from=tox /etc/tox-bootstrapd.conf /etc/
COPY entrypoint.sh /
RUN mkdir -p /var/lib/tox-bootstrapd/ /var/run/tox-bootstrapd/ \
&& chown tox:tox /var/lib/tox-bootstrapd/ /var/run/tox-bootstrapd/
# Public Key: 122837CCDD474DD1183A83152164D51427044B3EAAA52ED683F6BA602568673B
COPY keys /var/lib/tox-bootstrapd/
USER tox
# Use this to generate a keys file:
#RUN /usr/local/bin/tox-bootstrapd --config /etc/tox-bootstrapd.conf --log-backend stdout \
# && sleep 1
WORKDIR /web
CMD ["/entrypoint.sh"]

View File

@ -0,0 +1,6 @@
#!/bin/sh
set -eux
/usr/local/bin/tox-bootstrapd --config /etc/tox-bootstrapd.conf --log-backend stdout
/usr/local/bin/websockify -l "0.0.0.0:$PORT" -t 127.0.0.1:33445

View File

@ -0,0 +1 @@
(7ĚÝGMŃ:<3A>!dŐ'K>ŞĄ.Ö<>öş`%hg;„GÄŮYŞ:ĘZy5<79>ŁSŕ$Í|CÚ ŚÇ¸2Ě  t

View File

@ -0,0 +1,7 @@
module github.com/TokTok/c-toxcore/other/bootstrap_daemon/websocket/websockify
go 1.17
require (
github.com/gorilla/websocket master
)

View File

@ -0,0 +1,111 @@
// A Go version WebSocket to TCP socket proxy
//
// This is a heavily modified version of this file:
// https://github.com/novnc/websockify-other/blob/master/golang/websockify.go
//
// Changes include:
// - Fix infinite loop on error.
// - Proper logging.
// - Proper error handling in general.
// - Support both websocket and regular GET requests on /.
//
// Copyright 2022 The TokTok team.
// Copyright 2021 Michael.liu.
// See LICENSE for licensing conditions.
package main
import (
"encoding/hex"
"flag"
"log"
"net"
"net/http"
"github.com/gorilla/websocket"
)
var (
sourceAddr = flag.String("l", "127.0.0.1:8080", "http service address")
targetAddr = flag.String("t", "127.0.0.1:5900", "tcp service address")
)
var upgrader = websocket.Upgrader{
// Should be enough to fit any Tox TCP packets.
ReadBufferSize: 2048,
WriteBufferSize: 2048,
Subprotocols: []string{"binary"},
CheckOrigin: func(r *http.Request) bool {
return true
},
}
func forwardTCP(wsconn *websocket.Conn, conn net.Conn) {
var tcpbuffer [2048]byte
defer wsconn.Close()
defer conn.Close()
for {
n, err := conn.Read(tcpbuffer[0:])
if err != nil {
log.Println("TCP READ :", err)
break
}
log.Println("TCP READ :", n, hex.EncodeToString(tcpbuffer[0:n]))
if err := wsconn.WriteMessage(websocket.BinaryMessage, tcpbuffer[0:n]); err != nil {
log.Println("WS WRITE :", err)
break
}
log.Println("WS WRITE :", n)
}
}
func forwardWeb(wsconn *websocket.Conn, conn net.Conn) {
defer wsconn.Close()
defer conn.Close()
for {
_, buffer, err := wsconn.ReadMessage()
if err != nil {
log.Println("WS READ :", err)
break
}
log.Println("WS READ :", len(buffer), hex.EncodeToString(buffer))
m, err := conn.Write(buffer)
if err != nil {
log.Println("TCP WRITE:", err)
break
}
log.Println("TCP WRITE:", m)
}
}
func serveWs(w http.ResponseWriter, r *http.Request) {
ws, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println("upgrade:", err)
return
}
vnc, err := net.Dial("tcp", *targetAddr)
if err != nil {
log.Println("dial:", err)
return
}
go forwardTCP(ws, vnc)
go forwardWeb(ws, vnc)
}
func main() {
flag.Parse()
log.Println("Starting up websockify endpoint")
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Upgrade") == "websocket" {
serveWs(w, r)
} else {
http.ServeFile(w, r, r.URL.Path[1:])
}
})
log.Fatal(http.ListenAndServe(*sourceAddr, nil))
}

View File

@ -0,0 +1,84 @@
FROM ubuntu:20.04
ENV DEBIAN_FRONTEND="noninteractive"
# Install dependencies.
RUN apt-get update && apt-get install --no-install-recommends -y \
autoconf \
automake \
ca-certificates \
cmake \
curl \
git \
libtool \
make \
ninja-build \
pkg-config \
python3 \
unzip \
wget \
xz-utils \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /work/emsdk
RUN git clone --depth=1 https://github.com/emscripten-core/emsdk /work/emsdk \
&& ./emsdk install latest \
&& ./emsdk activate latest
# Build libsodium.
RUN . "/work/emsdk/emsdk_env.sh" \
&& git clone --depth=1 --branch=1.0.18 https://github.com/jedisct1/libsodium /work/libsodium \
&& cd /work/libsodium \
&& autoreconf -fi \
&& emconfigure ./configure --disable-shared \
--without-pthreads \
--disable-ssp --disable-asm --disable-pie \
&& emmake make install -j8
# Build an unused libsodium binding first so emcc caches all the system
# libraries. This makes rebuilds of toxcore below much faster.
RUN . "/work/emsdk/emsdk_env.sh" \
&& mkdir -p /work/wasm \
&& emcc -O3 -flto \
--closure=1 \
-s ALLOW_UNIMPLEMENTED_SYSCALLS=1 \
-s EXPORT_NAME=libtoxcore \
-s IGNORE_MISSING_MAIN=1 \
-s MAIN_MODULE=1 \
-s MALLOC=emmalloc \
-s MODULARIZE=1 \
-s STRICT=1 \
-s WEBSOCKET_URL=wss:// \
/usr/local/lib/libsodium.a \
-o /work/wasm/libsodium.js
# Build c-toxcore.
COPY . /work/c-toxcore
RUN . "/work/emsdk/emsdk_env.sh" \
&& cd /work/c-toxcore \
&& emcmake cmake -B_build -H. -GNinja \
-DCMAKE_C_FLAGS="-O3 -flto -fPIC" \
-DBUILD_TOXAV=OFF \
-DENABLE_SHARED=OFF \
-DBOOTSTRAP_DAEMON=OFF \
-DCMAKE_INSTALL_PREFIX:PATH="/usr/local" \
-DMIN_LOGGER_LEVEL=DEBUG \
&& emmake cmake --build _build --parallel 8 --target install
# Build wasm bindings.
RUN . "/work/emsdk/emsdk_env.sh" \
&& mkdir -p /work/wasm \
&& emcc -O3 -flto \
--closure=1 \
-s ALLOW_UNIMPLEMENTED_SYSCALLS=1 \
-s EXPORT_NAME=libtoxcore \
-s IGNORE_MISSING_MAIN=1 \
-s MAIN_MODULE=1 \
-s MALLOC=emmalloc \
-s MODULARIZE=1 \
-s STRICT=1 \
-s WEBSOCKET_URL=wss:// \
/usr/local/lib/libsodium.a \
/usr/local/lib/libtoxcore.a \
-o /work/wasm/libtoxcore.js