Files
wehub-resource-sync e0e362d700
SDK Tests / changes (push) Successful in 2m29s
Real E2E Tests / changes (push) Successful in 2m29s
Deploy Docs Pages / build (push) Has been cancelled
Deploy Docs Pages / deploy (push) Has been cancelled
Real E2E Tests / JavaScript E2E (docker bridge) (push) Has been cancelled
Real E2E Tests / Python E2E (docker bridge) (push) Has been cancelled
Real E2E Tests / Java E2E (docker bridge) (push) Has been cancelled
Real E2E Tests / C# E2E (docker bridge) (push) Has been cancelled
Real E2E Tests / Go E2E (docker bridge) (push) Has been cancelled
Real E2E Tests / Real E2E CI (push) Has been cancelled
SDK Tests / SDK CI (push) Has been cancelled
SDK Tests / CLI Tests (push) Has been cancelled
SDK Tests / Python SDK Quality (code-interpreter) (push) Has been cancelled
SDK Tests / Python SDK Quality (sandbox) (push) Has been cancelled
SDK Tests / Python SDK Tests (code-interpreter) (push) Has been cancelled
SDK Tests / JavaScript SDK Quality And Tests (code-interpreter) (push) Has been cancelled
SDK Tests / JavaScript SDK Quality And Tests (sandbox) (push) Has been cancelled
SDK Tests / Python SDK Tests (sandbox) (push) Has been cancelled
SDK Tests / CLI Quality (push) Has been cancelled
SDK Tests / Kotlin SDK Quality And Tests (sandbox) (push) Has been cancelled
SDK Tests / Kotlin SDK Quality And Tests (code-interpreter) (push) Has been cancelled
SDK Tests / C# SDK Quality And Tests (code-interpreter) (push) Has been cancelled
SDK Tests / C# SDK Quality And Tests (sandbox) (push) Has been cancelled
SDK Tests / Go SDK Quality And Tests (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:39:33 +08:00

195 lines
4.3 KiB
Go

// Copyright 2025 Alibaba Group Holding Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"bytes"
"context"
"fmt"
"io"
"log"
"net/http"
"os"
"os/exec"
"strings"
"time"
)
func main() {
ctx := context.Background()
if err := run(ctx); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
}
func run(ctx context.Context) error {
ctx, cancel := context.WithCancel(ctx)
defer cancel()
vnc := &VNCServer{}
errs := make(chan error, 10)
go func() {
if err := vnc.Run(ctx); err != nil {
log.Println(err, "VNC server exited with error")
errs <- fmt.Errorf("VNC server exited with error: %w", err)
cancel()
}
}()
if err := vnc.WaitForReady(ctx); err != nil {
return fmt.Errorf("failed to wait for VNC server: %w", err)
}
chrome := &Chrome{}
go func() {
if err := chrome.Run(ctx); err != nil {
log.Println(err, "Chrome exited with error")
errs <- fmt.Errorf("Chrome exited with error: %w", err)
cancel()
}
}()
if err := chrome.WaitForReady(ctx); err != nil {
return fmt.Errorf("failed to wait for Chrome: %w", err)
}
log.Println("Chrome and VNC server are running")
<-ctx.Done()
errs <- ctx.Err()
// Return the first error (or nil))
return <-errs
}
type Chrome struct {
}
func (c *Chrome) Run(ctx context.Context) error {
cmd := exec.CommandContext(ctx, "/chrome.sh")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
var env []string
for _, e := range os.Environ() {
if strings.HasPrefix(e, "DISPLAY=") {
continue
}
env = append(env, e)
}
env = append(env, "DISPLAY=:1")
cmd.Env = env
return cmd.Run()
}
func (c *Chrome) WaitForReady(ctx context.Context) error {
u := "http://localhost:9222/json/version"
httpClient := &http.Client{}
httpClient.Timeout = 200 * time.Millisecond
for {
if ctx.Err() != nil {
return ctx.Err()
}
req, err := http.NewRequestWithContext(ctx, "GET", u, nil)
if err != nil {
return fmt.Errorf("failed to create HTTP request: %w", err)
}
// Send the HTTP request
response, err := httpClient.Do(req)
if err != nil {
log.Println("Waiting for Chrome to be ready", "url", u, "info", err)
time.Sleep(100 * time.Millisecond)
continue
}
defer response.Body.Close()
// Check for HTTP 200 OK
if response.StatusCode != http.StatusOK {
log.Println("Waiting for Chrome to be ready", "url", u, "status", response.Status)
time.Sleep(100 * time.Millisecond)
continue
}
b, err := io.ReadAll(response.Body)
if err != nil {
log.Println("Waiting for Chrome to be ready", "url", u, "info", err)
time.Sleep(100 * time.Millisecond)
continue
}
log.Println("Chrome is ready", "url", u, "response", string(b))
break
}
return nil
}
type VNCServer struct {
}
func (v *VNCServer) Run(ctx context.Context) error {
cmd := exec.CommandContext(ctx, "Xtigervnc", ":1", "-geometry", "1280x1024")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
log.Println("Starting VNC server", "command", cmd.String())
if err := cmd.Start(); err != nil {
return fmt.Errorf("failed to start VNC server: %w", err)
}
go func() {
<-ctx.Done()
if err := cmd.Process.Kill(); err != nil {
log.Println(err, "failed to kill VNC server")
}
}()
if err := cmd.Wait(); err != nil {
return fmt.Errorf("VNC server exited with error: %w", err)
}
return nil
}
func (v *VNCServer) WaitForReady(ctx context.Context) error {
for {
if ctx.Err() != nil {
return ctx.Err()
}
cmd := exec.CommandContext(ctx, "xdpyinfo", "-display", ":1")
var stdout bytes.Buffer
cmd.Stdout = &stdout
var stderr bytes.Buffer
cmd.Stderr = &stderr
if err := cmd.Run(); err != nil {
log.Println("Waiting for VNC server to be ready", "info", err)
time.Sleep(100 * time.Millisecond)
continue
}
log.Println("VNC is ready")
break
}
return nil
}