Skip to content
This repository has been archived by the owner on Dec 9, 2024. It is now read-only.

Commit

Permalink
Work in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
skhaz committed Nov 12, 2023
1 parent 5ce98fd commit fa8de5a
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 74 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ jobs:
- name: Checkout
uses: actions/checkout@v4

# - name: Run Lint
# uses: golangci/golangci-lint-action@v3
- name: Run Lint
uses: golangci/golangci-lint-action@v3

deploy:
runs-on: ubuntu-latest
Expand Down
50 changes: 2 additions & 48 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,53 +1,7 @@
FROM golang:1.21
WORKDIR /opt
COPY go.mod .
# COPY go.sum .
# RUN go mod download
COPY go.sum .
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -ldflags="-s -w" -trimpath -o app

FROM debian:bookworm-slim

RUN <<EOF
set -eux
apt-get update
apt-get install -y build-essential cmake git
EOF

COPY --from=node:20-bookworm /usr/local/bin/node /usr/local/bin/node
COPY --from=node:20-bookworm /usr/local/include/node /usr/local/include/node
COPY --from=node:20-bookworm /usr/local/lib/node_modules /usr/local/lib/node_modules

COPY --from=python:3.11-bookworm /usr/local/bin/python3 /usr/local/bin/python3
COPY --from=python:3.11-bookworm /usr/local/lib/python3.11 /usr/local/lib/python3.11
COPY --from=python:3.11-bookworm /usr/local/lib/libpython3.11.so.1.0 /usr/local/lib/libpython3.11.so.1.0

RUN <<-EOF
set -eux
python3 -m pip install conan
conan profile detect

cat <<PROFILE > ~/.conan2/profiles/webassembly
include(default)

[settings]
arch=wasm
os=Emscripten

[tool_requires]
*: emsdk/3.1.44
PROFILE
EOF

WORKDIR /opt
RUN git clone --depth 1 https://github.com/carimbolabs/carimbo.git
WORKDIR /opt/carimbo/build
RUN <<EOF
set -eux
conan install .. --output-folder=. --build=missing --profile=webassembly --settings compiler.cppstd=20 --settings build_type=Release
cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release
EOF

WORKDIR /opt
COPY --from=0 /opt/app .
ENTRYPOINT /opt/app
135 changes: 111 additions & 24 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,45 +1,132 @@
package main

import (
"bytes"
"encoding/json"
"archive/zip"
_ "embed"
"fmt"
"io"
"log"
"net/http"
"os"
"os/exec"
"regexp"
"strings"
)

type Message struct {
Stdout string `json:"stdout"`
Stderr string `json:"stderr"`
//go:embed index.html
var html []byte

type Runtime struct {
Script string
Binary string
}

func readZipFile(file *zip.File) ([]byte, error) {
rc, err := file.Open()
if err != nil {
return nil, err
}
defer rc.Close()

return io.ReadAll(rc)
}

func runtime(release string, r chan Runtime, errCh chan error) {
url := fmt.Sprintf("https://github.com/carimbolabs/carimbo/releases/download/v%s/WebAssembly.zip", release)

// Baixar o arquivo ZIP
fmt.Println("Baixando o arquivo ZIP...")
resp, err := http.Get(url)
if err != nil {
errCh <- err
return
}
defer resp.Body.Close()

body, err := io.ReadAll(resp.Body)
if err != nil {
errCh <- err
return
}
// Ler o conteúdo do arquivo ZIP
fmt.Println("Lendo o conteúdo do arquivo ZIP...")
// Criar um leitor para o corpo da resposta
readerAt := strings.NewReader(string(body))

// Criar o leitor ZIP usando io.ReaderAt
zr, err := zip.NewReader(readerAt, int64(len(body)))
if err != nil {
errCh <- err
return
}

// Procurar pelos arquivos desejados no ZIP
var scriptContent, binaryContent []byte
for _, file := range zr.File {
switch file.Name {
case "carimbo.js":
scriptContent, err = readZipFile(file)
if err != nil {
errCh <- err
return
}
case "carimbo.wasm":
binaryContent, err = readZipFile(file)
if err != nil {
errCh <- err
return
}
}
}

r <- Runtime{
Script: string(scriptContent),
Binary: string(binaryContent),
}
}

func handler(w http.ResponseWriter, r *http.Request) {
cmd := exec.Command("cmake", "--build", ".")
cmd.Dir = "/opt/carimbo/build"
var stdout, stderr bytes.Buffer
pattern := regexp.MustCompile(`/(?P<runtime>[^/]+)/(?P<org>[^/]+)/(?P<repo>[^/]+)/(?P<version>[^/]+)`)

match := pattern.FindStringSubmatch(r.URL.Path)
if len(match) == 0 {
w.WriteHeader(http.StatusBadRequest)
return
}

matches := make(map[string]string)
for i, name := range pattern.SubexpNames() {
if i != 0 && name != "" {
matches[name] = match[i]
}
}

cmd.Stdout = &stdout
cmd.Stderr = &stderr
cmd.Run()
// err := cmd.Run()
// if err != nil {
// w.Header().Set("Content-Type", "application/json")
// json.NewEncoder(w).Encode(message)
if len(matches) == 0 {
w.WriteHeader(http.StatusBadRequest)
return
}

// return
// }
runtimeCh := make(chan Runtime)
errCh := make(chan error)
go runtime(matches["runtime"], runtimeCh, errCh)

message := Message{
Stdout: stdout.String(),
Stderr: stderr.String(),
var runtime Runtime
select {
case runtime = <-runtimeCh:
case err := <-errCh:
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
}

w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(message)
w.Header().Set("Content-Type", "text/html")
fmt.Printf("Runtime: %+v\n", runtime.Script)
html = []byte(strings.ReplaceAll(string(html), "{{script}}", runtime.Script))

w.Write(html)
}

func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(fmt.Sprintf(":%s", os.Getenv("PORT")), nil)

log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", os.Getenv("PORT")), nil))
}

0 comments on commit fa8de5a

Please sign in to comment.