Skip to content
2 changes: 2 additions & 0 deletions components/execd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package main

import (
"fmt"
"os"

"github.com/alibaba/opensandbox/internal/version"

Expand All @@ -42,5 +43,6 @@ func main() {
log.Info("execd listening on %s", addr)
if err := engine.Run(addr); err != nil {
log.Error("failed to start execd server: %v", err)
os.Exit(1)
}
}
2 changes: 1 addition & 1 deletion components/execd/pkg/jupyter/auth/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func (c *Client) Get(url string) (*http.Response, error) {

// Post sends a POST request.
func (c *Client) Post(url, contentType string, body io.Reader) (*http.Response, error) {
req, err := http.NewRequest(http.MethodPut, url, body)
req, err := http.NewRequest(http.MethodPost, url, body)
if err != nil {
return nil, err
}
Expand Down
10 changes: 9 additions & 1 deletion components/execd/pkg/runtime/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ func (c *Controller) runCommand(ctx context.Context, request *ExecuteCodeRequest
if err != nil {
return fmt.Errorf("failed to get stdlog descriptor: %w", err)
}
defer stdout.Close()
defer stderr.Close()
stdoutPath := c.stdoutFileName(session)
stderrPath := c.stderrFileName(session)

Expand Down Expand Up @@ -135,6 +137,8 @@ func (c *Controller) runCommand(ctx context.Context, request *ExecuteCodeRequest

err = cmd.Start()
if err != nil {
close(done)
wg.Wait()
request.Hooks.OnExecuteInit(session)
request.Hooks.OnExecuteError(&execute.ErrorOutput{EName: "CommandExecError", EValue: err.Error()})
log.Error("CommandExecError: error starting commands: %v", err)
Expand Down Expand Up @@ -246,7 +250,11 @@ func (c *Controller) runBackgroundCommand(ctx context.Context, cancel context.Ca
cmd.Env = mergeEnvs(os.Environ(), extraEnv)

// use DevNull as stdin so interactive programs exit immediately.
cmd.Stdin = os.NewFile(uintptr(syscall.Stdin), os.DevNull)
devNull, err := os.Open(os.DevNull)
if err == nil {
cmd.Stdin = devNull
defer devNull.Close()
}

err = cmd.Start()
kernel := &commandKernel{
Expand Down
11 changes: 9 additions & 2 deletions components/execd/pkg/runtime/sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ func (c *Controller) executeSelectSQLQuery(ctx context.Context, request *Execute
}
result = append(result, row)
}
if err := rows.Err(); err != nil {
request.Hooks.OnExecuteError(&execute.ErrorOutput{EName: "RowIterationError", EValue: err.Error()})
return nil
}

queryResult := QueryResult{
Columns: columns,
Expand Down Expand Up @@ -155,8 +159,11 @@ func (c *Controller) executeUpdateSQLQuery(ctx context.Context, request *Execute

// getQueryType extracts the first token to decide which executor to use.
func (c *Controller) getQueryType(query string) string {
firstWord := strings.ToUpper(strings.Fields(query)[0])
return firstWord
fields := strings.Fields(query)
if len(fields) == 0 {
return ""
}
return strings.ToUpper(fields[0])
}

// initDB lazily opens the local sandbox database.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ def __init__(
headers = {
"User-Agent": self.connection_config.user_agent,
**self.connection_config.headers,
**self.execd_endpoint.headers,
}

# Execd API does not require authentication
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ def to_api_volume(volume: Volume):
from opensandbox.api.lifecycle.models.host import (
Host as ApiHost,
)
from opensandbox.api.lifecycle.models.ossfs import (
OSSFS as ApiOSSFS,
)
from opensandbox.api.lifecycle.models.ossfs_version import OSSFSVersion
from opensandbox.api.lifecycle.models.pvc import (
PVC as ApiPVC,
)
Expand All @@ -104,6 +108,17 @@ def to_api_volume(volume: Volume):
if volume.pvc is not None:
api_pvc = ApiPVC(claim_name=volume.pvc.claim_name)

api_ossfs = UNSET
if volume.ossfs is not None and volume.ossfs.access_key_id is not None and volume.ossfs.access_key_secret is not None:
api_ossfs = ApiOSSFS(
bucket=volume.ossfs.bucket,
endpoint=volume.ossfs.endpoint,
access_key_id=volume.ossfs.access_key_id,
access_key_secret=volume.ossfs.access_key_secret,
version=OSSFSVersion(volume.ossfs.version),
options=volume.ossfs.options if volume.ossfs.options is not None else UNSET,
)

api_sub_path = UNSET
if volume.sub_path is not None:
api_sub_path = volume.sub_path
Expand All @@ -114,6 +129,7 @@ def to_api_volume(volume: Volume):
read_only=volume.read_only,
host=api_host,
pvc=api_pvc,
ossfs=api_ossfs,
sub_path=api_sub_path,
)

Expand Down
4 changes: 0 additions & 4 deletions server/src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,6 @@ async def lifespan(app: FastAPI):
k8s_client=k8s_client,
)

# Create sandbox service after validation
from src.services.factory import create_sandbox_service

app.state.sandbox_service = create_sandbox_service()
except Exception as exc:
logger.error("Secure runtime validation failed: %s", exc)
raise
Expand Down
Loading