58 lines
1.6 KiB
Go
58 lines
1.6 KiB
Go
// Package agentlaunch persists the exact argv a runtime should execute.
|
|
package agentlaunch
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
)
|
|
|
|
// EnvSpecPath is the environment variable that holds the path to the launch spec file.
|
|
const EnvSpecPath = "AO_LAUNCH_SPEC"
|
|
|
|
// Spec describes the agent process the launcher trampoline should exec.
|
|
type Spec struct {
|
|
WorkspacePath string `json:"workspacePath"`
|
|
Argv []string `json:"argv"`
|
|
FallbackArgv []string `json:"fallbackArgv,omitempty"`
|
|
}
|
|
|
|
// WriteTemp serialises spec to a temporary JSON file and returns its path.
|
|
func WriteTemp(spec Spec) (string, error) {
|
|
file, err := os.CreateTemp(os.TempDir(), "ao-launch-*.json")
|
|
if err != nil {
|
|
return "", fmt.Errorf("create launch spec: %w", err)
|
|
}
|
|
path := file.Name()
|
|
enc := json.NewEncoder(file)
|
|
enc.SetEscapeHTML(false)
|
|
if err := enc.Encode(spec); err != nil {
|
|
_ = file.Close()
|
|
_ = os.Remove(path)
|
|
return "", fmt.Errorf("write launch spec: %w", err)
|
|
}
|
|
if err := file.Close(); err != nil {
|
|
_ = os.Remove(path)
|
|
return "", fmt.Errorf("close launch spec: %w", err)
|
|
}
|
|
return path, nil
|
|
}
|
|
|
|
// ReadAndRemove reads and deletes the spec file at path, returning its contents.
|
|
func ReadAndRemove(path string) (Spec, error) {
|
|
raw, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return Spec{}, fmt.Errorf("read launch spec: %w", err)
|
|
}
|
|
_ = os.Remove(path)
|
|
|
|
var spec Spec
|
|
if err := json.Unmarshal(raw, &spec); err != nil {
|
|
return Spec{}, fmt.Errorf("parse launch spec: %w", err)
|
|
}
|
|
if len(spec.Argv) == 0 {
|
|
return Spec{}, fmt.Errorf("launch spec: argv is required")
|
|
}
|
|
return spec, nil
|
|
}
|