forked from wrenn/wrenn
fix: resolve bugs and DRY violations in sandbox manager and API handlers
- Fix createFromSnapshot discarding memoryMB param (balloon optimization was dead) - Fix double dm-snapshot removal in Pause() cleanupPauseFailure path - Fix DestroySandbox RPC mapping all errors to CodeNotFound - Fix handleFailed event consumer missing pausing/resuming → error transitions - Fix stream resource leak in StreamUpload on early-return paths - Add envs/cwd fields to ExecRequest proto for foreground exec parity - Extract createResources rollback helper to eliminate 4x duplicated teardown - Remove unused chClient.ping method - Add .mcp.json to gitignore Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -55,3 +55,4 @@ internal/dashboard/static/*
|
||||
.dual-graph/
|
||||
# Added by code-review-graph
|
||||
.code-review-graph/
|
||||
.mcp.json
|
||||
|
||||
@ -119,6 +119,8 @@ func (h *execHandler) Exec(w http.ResponseWriter, r *http.Request) {
|
||||
Cmd: req.Cmd,
|
||||
Args: req.Args,
|
||||
TimeoutSec: req.TimeoutSec,
|
||||
Envs: req.Envs,
|
||||
Cwd: req.Cwd,
|
||||
}))
|
||||
if err != nil {
|
||||
status, code, msg := agentErrToHTTP(err)
|
||||
|
||||
@ -89,6 +89,12 @@ func (h *filesStreamHandler) StreamUpload(w http.ResponseWriter, r *http.Request
|
||||
|
||||
// Open client-streaming RPC to host agent.
|
||||
stream := agent.WriteFileStream(ctx)
|
||||
var streamClosed bool
|
||||
defer func() {
|
||||
if !streamClosed {
|
||||
stream.CloseAndReceive()
|
||||
}
|
||||
}()
|
||||
|
||||
// Send metadata first.
|
||||
if err := stream.Send(&pb.WriteFileStreamRequest{
|
||||
@ -127,6 +133,7 @@ func (h *filesStreamHandler) StreamUpload(w http.ResponseWriter, r *http.Request
|
||||
}
|
||||
|
||||
// Close and receive response.
|
||||
streamClosed = true
|
||||
if _, err := stream.CloseAndReceive(); err != nil {
|
||||
status, code, msg := agentErrToHTTP(err)
|
||||
writeError(w, status, code, msg)
|
||||
|
||||
@ -210,16 +210,14 @@ func (c *SandboxEventConsumer) handleStopped(ctx context.Context, sandboxID pgty
|
||||
// or the CP's background goroutine publishes a failure. Uses conditional update
|
||||
// to avoid clobbering concurrent operations.
|
||||
func (c *SandboxEventConsumer) handleFailed(ctx context.Context, sandboxID pgtype.UUID) {
|
||||
// Try running → error (VM crash pushed by host agent).
|
||||
// Try each possible pre-failure state until one matches.
|
||||
for _, fromStatus := range []string{"running", "starting", "pausing", "resuming"} {
|
||||
if _, err := c.db.UpdateSandboxStatusIf(ctx, db.UpdateSandboxStatusIfParams{
|
||||
ID: sandboxID, Status: "running", Status_2: "error",
|
||||
ID: sandboxID, Status: fromStatus, Status_2: "error",
|
||||
}); err == nil {
|
||||
return
|
||||
}
|
||||
// Try starting → error (create failed).
|
||||
_, _ = c.db.UpdateSandboxStatusIf(ctx, db.UpdateSandboxStatusIfParams{
|
||||
ID: sandboxID, Status: "starting", Status_2: "error",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (c *SandboxEventConsumer) handleAutoPaused(ctx context.Context, sandboxID pgtype.UUID, _ SandboxEvent) {
|
||||
|
||||
@ -78,15 +78,30 @@ type ExecResult struct {
|
||||
ExitCode int32
|
||||
}
|
||||
|
||||
// ExecOpts holds optional parameters for Exec.
|
||||
type ExecOpts struct {
|
||||
Envs map[string]string
|
||||
Cwd string
|
||||
}
|
||||
|
||||
// Exec runs a command inside the sandbox and collects all stdout/stderr output.
|
||||
// It blocks until the command completes.
|
||||
func (c *Client) Exec(ctx context.Context, cmd string, args ...string) (*ExecResult, error) {
|
||||
func (c *Client) Exec(ctx context.Context, cmd string, args []string, opts *ExecOpts) (*ExecResult, error) {
|
||||
stdin := false
|
||||
req := connect.NewRequest(&envdpb.StartRequest{
|
||||
Process: &envdpb.ProcessConfig{
|
||||
proc := &envdpb.ProcessConfig{
|
||||
Cmd: cmd,
|
||||
Args: args,
|
||||
},
|
||||
}
|
||||
if opts != nil {
|
||||
if len(opts.Envs) > 0 {
|
||||
proc.Envs = opts.Envs
|
||||
}
|
||||
if opts.Cwd != "" {
|
||||
proc.Cwd = &opts.Cwd
|
||||
}
|
||||
}
|
||||
req := connect.NewRequest(&envdpb.StartRequest{
|
||||
Process: proc,
|
||||
Stdin: &stdin,
|
||||
})
|
||||
|
||||
|
||||
@ -20,6 +20,7 @@ import (
|
||||
pb "git.omukk.dev/wrenn/wrenn/proto/hostagent/gen"
|
||||
"git.omukk.dev/wrenn/wrenn/proto/hostagent/gen/hostagentv1connect"
|
||||
|
||||
"git.omukk.dev/wrenn/wrenn/internal/envdclient"
|
||||
"git.omukk.dev/wrenn/wrenn/internal/sandbox"
|
||||
)
|
||||
|
||||
@ -90,8 +91,11 @@ func (s *Server) DestroySandbox(
|
||||
req *connect.Request[pb.DestroySandboxRequest],
|
||||
) (*connect.Response[pb.DestroySandboxResponse], error) {
|
||||
if err := s.mgr.Destroy(ctx, req.Msg.SandboxId); err != nil {
|
||||
if strings.Contains(err.Error(), "not found") {
|
||||
return nil, connect.NewError(connect.CodeNotFound, err)
|
||||
}
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
return connect.NewResponse(&pb.DestroySandboxResponse{}), nil
|
||||
}
|
||||
|
||||
@ -216,7 +220,12 @@ func (s *Server) Exec(
|
||||
execCtx, cancel := context.WithTimeout(ctx, timeout)
|
||||
defer cancel()
|
||||
|
||||
result, err := s.mgr.Exec(execCtx, msg.SandboxId, msg.Cmd, msg.Args...)
|
||||
var opts *envdclient.ExecOpts
|
||||
if len(msg.Envs) > 0 || msg.Cwd != "" {
|
||||
opts = &envdclient.ExecOpts{Envs: msg.Envs, Cwd: msg.Cwd}
|
||||
}
|
||||
|
||||
result, err := s.mgr.Exec(execCtx, msg.SandboxId, msg.Cmd, msg.Args, opts)
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("exec: %w", err))
|
||||
}
|
||||
|
||||
@ -201,24 +201,30 @@ func (m *Manager) Create(ctx context.Context, sandboxID string, teamID, template
|
||||
return nil, fmt.Errorf("create dm-snapshot: %w", err)
|
||||
}
|
||||
|
||||
res := &createResources{
|
||||
sandboxID: sandboxID,
|
||||
loops: m.loops,
|
||||
loopImage: baseRootfs,
|
||||
dmDevice: dmDev,
|
||||
cowPath: cowPath,
|
||||
slots: m.slots,
|
||||
}
|
||||
|
||||
// Allocate network slot.
|
||||
slotIdx, err := m.slots.Allocate()
|
||||
if err != nil {
|
||||
warnErr("dm-snapshot remove error", sandboxID, devicemapper.RemoveSnapshot(context.Background(), dmDev))
|
||||
os.Remove(cowPath)
|
||||
m.loops.Release(baseRootfs)
|
||||
res.rollback()
|
||||
return nil, fmt.Errorf("allocate network slot: %w", err)
|
||||
}
|
||||
res.slotIdx = slotIdx
|
||||
slot := network.NewSlot(slotIdx)
|
||||
|
||||
// Set up network.
|
||||
if err := network.CreateNetwork(slot); err != nil {
|
||||
m.slots.Release(slotIdx)
|
||||
warnErr("dm-snapshot remove error", sandboxID, devicemapper.RemoveSnapshot(context.Background(), dmDev))
|
||||
os.Remove(cowPath)
|
||||
m.loops.Release(baseRootfs)
|
||||
res.rollback()
|
||||
return nil, fmt.Errorf("create network: %w", err)
|
||||
}
|
||||
res.slot = slot
|
||||
|
||||
// Boot VM — CH gets the dm device path.
|
||||
vmCfg := vm.VMConfig{
|
||||
@ -238,13 +244,10 @@ func (m *Manager) Create(ctx context.Context, sandboxID string, teamID, template
|
||||
}
|
||||
|
||||
if _, err := m.vm.Create(ctx, vmCfg); err != nil {
|
||||
warnErr("network cleanup error", sandboxID, network.RemoveNetwork(slot))
|
||||
m.slots.Release(slotIdx)
|
||||
warnErr("dm-snapshot remove error", sandboxID, devicemapper.RemoveSnapshot(context.Background(), dmDev))
|
||||
os.Remove(cowPath)
|
||||
m.loops.Release(baseRootfs)
|
||||
res.rollback()
|
||||
return nil, fmt.Errorf("create VM: %w", err)
|
||||
}
|
||||
res.vm = m.vm
|
||||
|
||||
// Wait for envd to be ready.
|
||||
client := envdclient.New(slot.HostIP.String())
|
||||
@ -252,12 +255,7 @@ func (m *Manager) Create(ctx context.Context, sandboxID string, teamID, template
|
||||
defer waitCancel()
|
||||
|
||||
if err := client.WaitUntilReady(waitCtx); err != nil {
|
||||
warnErr("vm destroy error", sandboxID, m.vm.Destroy(context.Background(), sandboxID))
|
||||
warnErr("network cleanup error", sandboxID, network.RemoveNetwork(slot))
|
||||
m.slots.Release(slotIdx)
|
||||
warnErr("dm-snapshot remove error", sandboxID, devicemapper.RemoveSnapshot(context.Background(), dmDev))
|
||||
os.Remove(cowPath)
|
||||
m.loops.Release(baseRootfs)
|
||||
res.rollback()
|
||||
return nil, fmt.Errorf("wait for envd: %w", err)
|
||||
}
|
||||
|
||||
@ -538,14 +536,16 @@ func (m *Manager) Pause(ctx context.Context, sandboxID string) error {
|
||||
|
||||
// ── Step 7: Remove dm-snapshot and save CoW ──────────────────────
|
||||
if sb.dmDevice != nil {
|
||||
if err := devicemapper.RemoveSnapshot(ctx, sb.dmDevice); err != nil {
|
||||
dmDev := sb.dmDevice
|
||||
sb.dmDevice = nil
|
||||
if err := devicemapper.RemoveSnapshot(ctx, dmDev); err != nil {
|
||||
m.cleanupPauseFailure(sb, sandboxID, pauseDir)
|
||||
return fmt.Errorf("remove dm-snapshot: %w", err)
|
||||
}
|
||||
|
||||
snapshotCow := snapshot.CowPath(pauseDir, "")
|
||||
if err := os.Rename(sb.dmDevice.CowPath, snapshotCow); err != nil {
|
||||
os.Remove(sb.dmDevice.CowPath)
|
||||
if err := os.Rename(dmDev.CowPath, snapshotCow); err != nil {
|
||||
os.Remove(dmDev.CowPath)
|
||||
m.cleanupPauseFailure(sb, sandboxID, pauseDir)
|
||||
return fmt.Errorf("move cow file: %w", err)
|
||||
}
|
||||
@ -616,38 +616,42 @@ func (m *Manager) Resume(ctx context.Context, sandboxID string, timeoutSec int,
|
||||
return nil, fmt.Errorf("move cow file: %w", err)
|
||||
}
|
||||
|
||||
rollbackCow := func() {
|
||||
if err := os.Rename(cowPath, savedCow); err != nil {
|
||||
slog.Warn("failed to rollback cow file", "src", cowPath, "dst", savedCow, "error", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Restore dm-snapshot from existing persistent CoW file.
|
||||
dmName := "wrenn-" + sandboxID
|
||||
dmDev, err := devicemapper.RestoreSnapshot(ctx, dmName, originLoop, cowPath, originSize)
|
||||
if err != nil {
|
||||
m.loops.Release(baseImagePath)
|
||||
rollbackCow()
|
||||
os.Rename(cowPath, savedCow)
|
||||
return nil, fmt.Errorf("restore dm-snapshot: %w", err)
|
||||
}
|
||||
|
||||
res := &createResources{
|
||||
sandboxID: sandboxID,
|
||||
loops: m.loops,
|
||||
loopImage: baseImagePath,
|
||||
dmDevice: dmDev,
|
||||
slots: m.slots,
|
||||
rollCow: func() {
|
||||
if err := os.Rename(cowPath, savedCow); err != nil {
|
||||
slog.Warn("failed to rollback cow file", "src", cowPath, "dst", savedCow, "error", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
// Allocate network slot.
|
||||
slotIdx, err := m.slots.Allocate()
|
||||
if err != nil {
|
||||
warnErr("dm-snapshot remove error", sandboxID, devicemapper.RemoveSnapshot(context.Background(), dmDev))
|
||||
rollbackCow()
|
||||
m.loops.Release(baseImagePath)
|
||||
res.rollback()
|
||||
return nil, fmt.Errorf("allocate network slot: %w", err)
|
||||
}
|
||||
res.slotIdx = slotIdx
|
||||
slot := network.NewSlot(slotIdx)
|
||||
|
||||
if err := network.CreateNetwork(slot); err != nil {
|
||||
m.slots.Release(slotIdx)
|
||||
warnErr("dm-snapshot remove error", sandboxID, devicemapper.RemoveSnapshot(context.Background(), dmDev))
|
||||
rollbackCow()
|
||||
m.loops.Release(baseImagePath)
|
||||
res.rollback()
|
||||
return nil, fmt.Errorf("create network: %w", err)
|
||||
}
|
||||
res.slot = slot
|
||||
|
||||
// Restore VM from CH snapshot.
|
||||
vmCfg := vm.VMConfig{
|
||||
@ -655,6 +659,7 @@ func (m *Manager) Resume(ctx context.Context, sandboxID string, timeoutSec int,
|
||||
TemplateID: meta.TemplateID,
|
||||
KernelPath: m.resolveKernelPath(kernelVersion),
|
||||
RootfsPath: dmDev.DevicePath,
|
||||
MemoryMB: meta.MemoryMB,
|
||||
NetworkNamespace: slot.NamespaceID,
|
||||
TapDevice: slot.TapName,
|
||||
TapMAC: slot.TapMAC,
|
||||
@ -665,13 +670,10 @@ func (m *Manager) Resume(ctx context.Context, sandboxID string, timeoutSec int,
|
||||
}
|
||||
|
||||
if _, err := m.vm.CreateFromSnapshot(ctx, vmCfg, pauseDir); err != nil {
|
||||
warnErr("network cleanup error", sandboxID, network.RemoveNetwork(slot))
|
||||
m.slots.Release(slotIdx)
|
||||
warnErr("dm-snapshot remove error", sandboxID, devicemapper.RemoveSnapshot(context.Background(), dmDev))
|
||||
rollbackCow()
|
||||
m.loops.Release(baseImagePath)
|
||||
res.rollback()
|
||||
return nil, fmt.Errorf("restore VM from snapshot: %w", err)
|
||||
}
|
||||
res.vm = m.vm
|
||||
|
||||
// Wait for envd to be ready.
|
||||
client := envdclient.New(slot.HostIP.String())
|
||||
@ -679,12 +681,7 @@ func (m *Manager) Resume(ctx context.Context, sandboxID string, timeoutSec int,
|
||||
|
||||
if err := client.WaitUntilReady(waitCtx); err != nil {
|
||||
waitCancel()
|
||||
warnErr("vm destroy error", sandboxID, m.vm.Destroy(context.Background(), sandboxID))
|
||||
warnErr("network cleanup error", sandboxID, network.RemoveNetwork(slot))
|
||||
m.slots.Release(slotIdx)
|
||||
warnErr("dm-snapshot remove error", sandboxID, devicemapper.RemoveSnapshot(context.Background(), dmDev))
|
||||
rollbackCow()
|
||||
m.loops.Release(baseImagePath)
|
||||
res.rollback()
|
||||
return nil, fmt.Errorf("wait for envd: %w", err)
|
||||
}
|
||||
waitCancel()
|
||||
@ -905,7 +902,7 @@ func (m *Manager) FlattenRootfs(ctx context.Context, sandboxID string, teamID, t
|
||||
func() {
|
||||
syncCtx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||
defer cancel()
|
||||
if _, err := sb.client.Exec(syncCtx, "/bin/sync"); err != nil {
|
||||
if _, err := sb.client.Exec(syncCtx, "/bin/sync", nil, nil); err != nil {
|
||||
slog.Warn("flatten: guest sync failed (non-fatal)", "id", sb.ID, "error", err)
|
||||
}
|
||||
}()
|
||||
@ -1001,7 +998,7 @@ func (m *Manager) DeleteSnapshot(teamID, templateID pgtype.UUID) error {
|
||||
// CH handles memory restore internally (with on-demand paging).
|
||||
// The template's rootfs.ext4 is a flattened standalone image — we create a
|
||||
// dm-snapshot on top of it just like a normal Create.
|
||||
func (m *Manager) createFromSnapshot(ctx context.Context, sandboxID string, teamID, templateID pgtype.UUID, vcpus, _, timeoutSec, diskSizeMB int) (*models.Sandbox, error) {
|
||||
func (m *Manager) createFromSnapshot(ctx context.Context, sandboxID string, teamID, templateID pgtype.UUID, vcpus, memoryMB, timeoutSec, diskSizeMB int) (*models.Sandbox, error) {
|
||||
tmplDir := layout.TemplateDir(m.cfg.WrennDir, teamID, templateID)
|
||||
|
||||
// Set up dm-snapshot on the template's flattened rootfs.
|
||||
@ -1026,23 +1023,29 @@ func (m *Manager) createFromSnapshot(ctx context.Context, sandboxID string, team
|
||||
return nil, fmt.Errorf("create dm-snapshot: %w", err)
|
||||
}
|
||||
|
||||
res := &createResources{
|
||||
sandboxID: sandboxID,
|
||||
loops: m.loops,
|
||||
loopImage: baseRootfs,
|
||||
dmDevice: dmDev,
|
||||
cowPath: cowPath,
|
||||
slots: m.slots,
|
||||
}
|
||||
|
||||
// Allocate network.
|
||||
slotIdx, err := m.slots.Allocate()
|
||||
if err != nil {
|
||||
warnErr("dm-snapshot remove error", sandboxID, devicemapper.RemoveSnapshot(context.Background(), dmDev))
|
||||
os.Remove(cowPath)
|
||||
m.loops.Release(baseRootfs)
|
||||
res.rollback()
|
||||
return nil, fmt.Errorf("allocate network slot: %w", err)
|
||||
}
|
||||
res.slotIdx = slotIdx
|
||||
slot := network.NewSlot(slotIdx)
|
||||
|
||||
if err := network.CreateNetwork(slot); err != nil {
|
||||
m.slots.Release(slotIdx)
|
||||
warnErr("dm-snapshot remove error", sandboxID, devicemapper.RemoveSnapshot(context.Background(), dmDev))
|
||||
os.Remove(cowPath)
|
||||
m.loops.Release(baseRootfs)
|
||||
res.rollback()
|
||||
return nil, fmt.Errorf("create network: %w", err)
|
||||
}
|
||||
res.slot = slot
|
||||
|
||||
// Restore VM from CH snapshot.
|
||||
vmCfg := vm.VMConfig{
|
||||
@ -1051,6 +1054,7 @@ func (m *Manager) createFromSnapshot(ctx context.Context, sandboxID string, team
|
||||
KernelPath: m.cfg.KernelPath,
|
||||
RootfsPath: dmDev.DevicePath,
|
||||
VCPUs: vcpus,
|
||||
MemoryMB: memoryMB,
|
||||
NetworkNamespace: slot.NamespaceID,
|
||||
TapDevice: slot.TapName,
|
||||
TapMAC: slot.TapMAC,
|
||||
@ -1061,13 +1065,10 @@ func (m *Manager) createFromSnapshot(ctx context.Context, sandboxID string, team
|
||||
}
|
||||
|
||||
if _, err := m.vm.CreateFromSnapshot(ctx, vmCfg, tmplDir); err != nil {
|
||||
warnErr("network cleanup error", sandboxID, network.RemoveNetwork(slot))
|
||||
m.slots.Release(slotIdx)
|
||||
warnErr("dm-snapshot remove error", sandboxID, devicemapper.RemoveSnapshot(context.Background(), dmDev))
|
||||
os.Remove(cowPath)
|
||||
m.loops.Release(baseRootfs)
|
||||
res.rollback()
|
||||
return nil, fmt.Errorf("restore VM from snapshot: %w", err)
|
||||
}
|
||||
res.vm = m.vm
|
||||
|
||||
// Wait for envd.
|
||||
client := envdclient.New(slot.HostIP.String())
|
||||
@ -1075,12 +1076,7 @@ func (m *Manager) createFromSnapshot(ctx context.Context, sandboxID string, team
|
||||
|
||||
if err := client.WaitUntilReady(waitCtx); err != nil {
|
||||
waitCancel()
|
||||
warnErr("vm destroy error", sandboxID, m.vm.Destroy(context.Background(), sandboxID))
|
||||
warnErr("network cleanup error", sandboxID, network.RemoveNetwork(slot))
|
||||
m.slots.Release(slotIdx)
|
||||
warnErr("dm-snapshot remove error", sandboxID, devicemapper.RemoveSnapshot(context.Background(), dmDev))
|
||||
os.Remove(cowPath)
|
||||
m.loops.Release(baseRootfs)
|
||||
res.rollback()
|
||||
return nil, fmt.Errorf("wait for envd: %w", err)
|
||||
}
|
||||
waitCancel()
|
||||
@ -1109,6 +1105,7 @@ func (m *Manager) createFromSnapshot(ctx context.Context, sandboxID string, team
|
||||
TemplateTeamID: teamID.Bytes,
|
||||
TemplateID: templateID.Bytes,
|
||||
VCPUs: vcpus,
|
||||
MemoryMB: memoryMB,
|
||||
TimeoutSec: timeoutSec,
|
||||
SlotIndex: slotIdx,
|
||||
HostIP: slot.HostIP,
|
||||
@ -1143,7 +1140,7 @@ func (m *Manager) createFromSnapshot(ctx context.Context, sandboxID string, team
|
||||
}
|
||||
|
||||
// Exec runs a command inside a sandbox.
|
||||
func (m *Manager) Exec(ctx context.Context, sandboxID string, cmd string, args ...string) (*envdclient.ExecResult, error) {
|
||||
func (m *Manager) Exec(ctx context.Context, sandboxID string, cmd string, args []string, opts *envdclient.ExecOpts) (*envdclient.ExecResult, error) {
|
||||
sb, err := m.get(sandboxID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -1157,7 +1154,7 @@ func (m *Manager) Exec(ctx context.Context, sandboxID string, cmd string, args .
|
||||
sb.LastActiveAt = time.Now()
|
||||
m.mu.Unlock()
|
||||
|
||||
return sb.client.Exec(ctx, cmd, args...)
|
||||
return sb.client.Exec(ctx, cmd, args, opts)
|
||||
}
|
||||
|
||||
// ExecStream runs a command inside a sandbox and returns a channel of streaming events.
|
||||
@ -1538,6 +1535,44 @@ func warnErr(msg string, id string, err error) {
|
||||
}
|
||||
}
|
||||
|
||||
// createResources tracks partially-acquired resources during sandbox creation
|
||||
// so they can be rolled back in reverse order on failure.
|
||||
type createResources struct {
|
||||
sandboxID string
|
||||
loops *devicemapper.LoopRegistry
|
||||
vm *vm.Manager
|
||||
loopImage string
|
||||
dmDevice *devicemapper.SnapshotDevice
|
||||
cowPath string
|
||||
slotIdx int
|
||||
slots *network.SlotAllocator
|
||||
slot *network.Slot
|
||||
rollCow func() // optional custom cow rollback (e.g. rename back)
|
||||
}
|
||||
|
||||
func (r *createResources) rollback() {
|
||||
if r.vm != nil && r.sandboxID != "" {
|
||||
warnErr("vm destroy error", r.sandboxID, r.vm.Destroy(context.Background(), r.sandboxID))
|
||||
}
|
||||
if r.slot != nil {
|
||||
warnErr("network cleanup error", r.sandboxID, network.RemoveNetwork(r.slot))
|
||||
}
|
||||
if r.slots != nil && r.slotIdx > 0 {
|
||||
r.slots.Release(r.slotIdx)
|
||||
}
|
||||
if r.dmDevice != nil {
|
||||
warnErr("dm-snapshot remove error", r.sandboxID, devicemapper.RemoveSnapshot(context.Background(), r.dmDevice))
|
||||
}
|
||||
if r.rollCow != nil {
|
||||
r.rollCow()
|
||||
} else if r.cowPath != "" {
|
||||
os.Remove(r.cowPath)
|
||||
}
|
||||
if r.loopImage != "" {
|
||||
r.loops.Release(r.loopImage)
|
||||
}
|
||||
}
|
||||
|
||||
// startCrashWatcher monitors the VM process for unexpected exits.
|
||||
// If the process exits while the sandbox is still in m.boxes (i.e. not a
|
||||
// deliberate Destroy), the sandbox is cleaned up and a sandbox.error event
|
||||
|
||||
@ -206,8 +206,3 @@ func (c *chClient) resizeBalloon(ctx context.Context, sizeBytes int64) error {
|
||||
"desired_balloon": sizeBytes,
|
||||
})
|
||||
}
|
||||
|
||||
// ping checks if the VMM is alive and ready to accept commands.
|
||||
func (c *chClient) ping(ctx context.Context) error {
|
||||
return c.do(ctx, http.MethodGet, "/api/v1/vmm.ping", nil)
|
||||
}
|
||||
|
||||
@ -760,6 +760,10 @@ type ExecRequest struct {
|
||||
Args []string `protobuf:"bytes,3,rep,name=args,proto3" json:"args,omitempty"`
|
||||
// Timeout for the command in seconds (default: 30).
|
||||
TimeoutSec int32 `protobuf:"varint,4,opt,name=timeout_sec,json=timeoutSec,proto3" json:"timeout_sec,omitempty"`
|
||||
// Environment variables to set for the command.
|
||||
Envs map[string]string `protobuf:"bytes,5,rep,name=envs,proto3" json:"envs,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
|
||||
// Working directory for the command.
|
||||
Cwd string `protobuf:"bytes,6,opt,name=cwd,proto3" json:"cwd,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
@ -822,6 +826,20 @@ func (x *ExecRequest) GetTimeoutSec() int32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *ExecRequest) GetEnvs() map[string]string {
|
||||
if x != nil {
|
||||
return x.Envs
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ExecRequest) GetCwd() string {
|
||||
if x != nil {
|
||||
return x.Cwd
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type ExecResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Stdout []byte `protobuf:"bytes,1,opt,name=stdout,proto3" json:"stdout,omitempty"`
|
||||
@ -4196,14 +4214,19 @@ const file_hostagent_proto_rawDesc = "" +
|
||||
"\ateam_id\x18\x02 \x01(\tR\x06teamId\x12\x1f\n" +
|
||||
"\vtemplate_id\x18\x03 \x01(\tR\n" +
|
||||
"templateId\"\x18\n" +
|
||||
"\x16DeleteSnapshotResponse\"s\n" +
|
||||
"\x16DeleteSnapshotResponse\"\xf7\x01\n" +
|
||||
"\vExecRequest\x12\x1d\n" +
|
||||
"\n" +
|
||||
"sandbox_id\x18\x01 \x01(\tR\tsandboxId\x12\x10\n" +
|
||||
"\x03cmd\x18\x02 \x01(\tR\x03cmd\x12\x12\n" +
|
||||
"\x04args\x18\x03 \x03(\tR\x04args\x12\x1f\n" +
|
||||
"\vtimeout_sec\x18\x04 \x01(\x05R\n" +
|
||||
"timeoutSec\"[\n" +
|
||||
"timeoutSec\x127\n" +
|
||||
"\x04envs\x18\x05 \x03(\v2#.hostagent.v1.ExecRequest.EnvsEntryR\x04envs\x12\x10\n" +
|
||||
"\x03cwd\x18\x06 \x01(\tR\x03cwd\x1a7\n" +
|
||||
"\tEnvsEntry\x12\x10\n" +
|
||||
"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
|
||||
"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"[\n" +
|
||||
"\fExecResponse\x12\x16\n" +
|
||||
"\x06stdout\x18\x01 \x01(\fR\x06stdout\x12\x16\n" +
|
||||
"\x06stderr\x18\x02 \x01(\fR\x06stderr\x12\x1b\n" +
|
||||
@ -4486,7 +4509,7 @@ func file_hostagent_proto_rawDescGZIP() []byte {
|
||||
return file_hostagent_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_hostagent_proto_msgTypes = make([]protoimpl.MessageInfo, 76)
|
||||
var file_hostagent_proto_msgTypes = make([]protoimpl.MessageInfo, 77)
|
||||
var file_hostagent_proto_goTypes = []any{
|
||||
(*CreateSandboxRequest)(nil), // 0: hostagent.v1.CreateSandboxRequest
|
||||
(*CreateSandboxResponse)(nil), // 1: hostagent.v1.CreateSandboxResponse
|
||||
@ -4561,99 +4584,101 @@ var file_hostagent_proto_goTypes = []any{
|
||||
nil, // 70: hostagent.v1.CreateSandboxResponse.MetadataEntry
|
||||
nil, // 71: hostagent.v1.ResumeSandboxRequest.DefaultEnvEntry
|
||||
nil, // 72: hostagent.v1.ResumeSandboxResponse.MetadataEntry
|
||||
nil, // 73: hostagent.v1.SandboxInfo.MetadataEntry
|
||||
nil, // 74: hostagent.v1.PtyAttachRequest.EnvsEntry
|
||||
nil, // 75: hostagent.v1.StartBackgroundRequest.EnvsEntry
|
||||
nil, // 73: hostagent.v1.ExecRequest.EnvsEntry
|
||||
nil, // 74: hostagent.v1.SandboxInfo.MetadataEntry
|
||||
nil, // 75: hostagent.v1.PtyAttachRequest.EnvsEntry
|
||||
nil, // 76: hostagent.v1.StartBackgroundRequest.EnvsEntry
|
||||
}
|
||||
var file_hostagent_proto_depIdxs = []int32{
|
||||
69, // 0: hostagent.v1.CreateSandboxRequest.default_env:type_name -> hostagent.v1.CreateSandboxRequest.DefaultEnvEntry
|
||||
70, // 1: hostagent.v1.CreateSandboxResponse.metadata:type_name -> hostagent.v1.CreateSandboxResponse.MetadataEntry
|
||||
71, // 2: hostagent.v1.ResumeSandboxRequest.default_env:type_name -> hostagent.v1.ResumeSandboxRequest.DefaultEnvEntry
|
||||
72, // 3: hostagent.v1.ResumeSandboxResponse.metadata:type_name -> hostagent.v1.ResumeSandboxResponse.MetadataEntry
|
||||
16, // 4: hostagent.v1.ListSandboxesResponse.sandboxes:type_name -> hostagent.v1.SandboxInfo
|
||||
73, // 5: hostagent.v1.SandboxInfo.metadata:type_name -> hostagent.v1.SandboxInfo.MetadataEntry
|
||||
23, // 6: hostagent.v1.ExecStreamResponse.start:type_name -> hostagent.v1.ExecStreamStart
|
||||
24, // 7: hostagent.v1.ExecStreamResponse.data:type_name -> hostagent.v1.ExecStreamData
|
||||
25, // 8: hostagent.v1.ExecStreamResponse.end:type_name -> hostagent.v1.ExecStreamEnd
|
||||
27, // 9: hostagent.v1.WriteFileStreamRequest.meta:type_name -> hostagent.v1.WriteFileStreamMeta
|
||||
33, // 10: hostagent.v1.ListDirResponse.entries:type_name -> hostagent.v1.FileEntry
|
||||
33, // 11: hostagent.v1.MakeDirResponse.entry:type_name -> hostagent.v1.FileEntry
|
||||
42, // 12: hostagent.v1.GetSandboxMetricsResponse.points:type_name -> hostagent.v1.MetricPoint
|
||||
42, // 13: hostagent.v1.FlushSandboxMetricsResponse.points_10m:type_name -> hostagent.v1.MetricPoint
|
||||
42, // 14: hostagent.v1.FlushSandboxMetricsResponse.points_2h:type_name -> hostagent.v1.MetricPoint
|
||||
42, // 15: hostagent.v1.FlushSandboxMetricsResponse.points_24h:type_name -> hostagent.v1.MetricPoint
|
||||
74, // 16: hostagent.v1.PtyAttachRequest.envs:type_name -> hostagent.v1.PtyAttachRequest.EnvsEntry
|
||||
51, // 17: hostagent.v1.PtyAttachResponse.started:type_name -> hostagent.v1.PtyStarted
|
||||
52, // 18: hostagent.v1.PtyAttachResponse.output:type_name -> hostagent.v1.PtyOutput
|
||||
53, // 19: hostagent.v1.PtyAttachResponse.exited:type_name -> hostagent.v1.PtyExited
|
||||
75, // 20: hostagent.v1.StartBackgroundRequest.envs:type_name -> hostagent.v1.StartBackgroundRequest.EnvsEntry
|
||||
63, // 21: hostagent.v1.ListProcessesResponse.processes:type_name -> hostagent.v1.ProcessEntry
|
||||
23, // 22: hostagent.v1.ConnectProcessResponse.start:type_name -> hostagent.v1.ExecStreamStart
|
||||
24, // 23: hostagent.v1.ConnectProcessResponse.data:type_name -> hostagent.v1.ExecStreamData
|
||||
25, // 24: hostagent.v1.ConnectProcessResponse.end:type_name -> hostagent.v1.ExecStreamEnd
|
||||
0, // 25: hostagent.v1.HostAgentService.CreateSandbox:input_type -> hostagent.v1.CreateSandboxRequest
|
||||
2, // 26: hostagent.v1.HostAgentService.DestroySandbox:input_type -> hostagent.v1.DestroySandboxRequest
|
||||
4, // 27: hostagent.v1.HostAgentService.PauseSandbox:input_type -> hostagent.v1.PauseSandboxRequest
|
||||
6, // 28: hostagent.v1.HostAgentService.ResumeSandbox:input_type -> hostagent.v1.ResumeSandboxRequest
|
||||
12, // 29: hostagent.v1.HostAgentService.Exec:input_type -> hostagent.v1.ExecRequest
|
||||
14, // 30: hostagent.v1.HostAgentService.ListSandboxes:input_type -> hostagent.v1.ListSandboxesRequest
|
||||
17, // 31: hostagent.v1.HostAgentService.WriteFile:input_type -> hostagent.v1.WriteFileRequest
|
||||
19, // 32: hostagent.v1.HostAgentService.ReadFile:input_type -> hostagent.v1.ReadFileRequest
|
||||
31, // 33: hostagent.v1.HostAgentService.ListDir:input_type -> hostagent.v1.ListDirRequest
|
||||
34, // 34: hostagent.v1.HostAgentService.MakeDir:input_type -> hostagent.v1.MakeDirRequest
|
||||
36, // 35: hostagent.v1.HostAgentService.RemovePath:input_type -> hostagent.v1.RemovePathRequest
|
||||
8, // 36: hostagent.v1.HostAgentService.CreateSnapshot:input_type -> hostagent.v1.CreateSnapshotRequest
|
||||
10, // 37: hostagent.v1.HostAgentService.DeleteSnapshot:input_type -> hostagent.v1.DeleteSnapshotRequest
|
||||
21, // 38: hostagent.v1.HostAgentService.ExecStream:input_type -> hostagent.v1.ExecStreamRequest
|
||||
26, // 39: hostagent.v1.HostAgentService.WriteFileStream:input_type -> hostagent.v1.WriteFileStreamRequest
|
||||
29, // 40: hostagent.v1.HostAgentService.ReadFileStream:input_type -> hostagent.v1.ReadFileStreamRequest
|
||||
38, // 41: hostagent.v1.HostAgentService.PingSandbox:input_type -> hostagent.v1.PingSandboxRequest
|
||||
40, // 42: hostagent.v1.HostAgentService.Terminate:input_type -> hostagent.v1.TerminateRequest
|
||||
43, // 43: hostagent.v1.HostAgentService.GetSandboxMetrics:input_type -> hostagent.v1.GetSandboxMetricsRequest
|
||||
45, // 44: hostagent.v1.HostAgentService.FlushSandboxMetrics:input_type -> hostagent.v1.FlushSandboxMetricsRequest
|
||||
47, // 45: hostagent.v1.HostAgentService.FlattenRootfs:input_type -> hostagent.v1.FlattenRootfsRequest
|
||||
49, // 46: hostagent.v1.HostAgentService.PtyAttach:input_type -> hostagent.v1.PtyAttachRequest
|
||||
54, // 47: hostagent.v1.HostAgentService.PtySendInput:input_type -> hostagent.v1.PtySendInputRequest
|
||||
56, // 48: hostagent.v1.HostAgentService.PtyResize:input_type -> hostagent.v1.PtyResizeRequest
|
||||
58, // 49: hostagent.v1.HostAgentService.PtyKill:input_type -> hostagent.v1.PtyKillRequest
|
||||
60, // 50: hostagent.v1.HostAgentService.StartBackground:input_type -> hostagent.v1.StartBackgroundRequest
|
||||
62, // 51: hostagent.v1.HostAgentService.ListProcesses:input_type -> hostagent.v1.ListProcessesRequest
|
||||
65, // 52: hostagent.v1.HostAgentService.KillProcess:input_type -> hostagent.v1.KillProcessRequest
|
||||
67, // 53: hostagent.v1.HostAgentService.ConnectProcess:input_type -> hostagent.v1.ConnectProcessRequest
|
||||
1, // 54: hostagent.v1.HostAgentService.CreateSandbox:output_type -> hostagent.v1.CreateSandboxResponse
|
||||
3, // 55: hostagent.v1.HostAgentService.DestroySandbox:output_type -> hostagent.v1.DestroySandboxResponse
|
||||
5, // 56: hostagent.v1.HostAgentService.PauseSandbox:output_type -> hostagent.v1.PauseSandboxResponse
|
||||
7, // 57: hostagent.v1.HostAgentService.ResumeSandbox:output_type -> hostagent.v1.ResumeSandboxResponse
|
||||
13, // 58: hostagent.v1.HostAgentService.Exec:output_type -> hostagent.v1.ExecResponse
|
||||
15, // 59: hostagent.v1.HostAgentService.ListSandboxes:output_type -> hostagent.v1.ListSandboxesResponse
|
||||
18, // 60: hostagent.v1.HostAgentService.WriteFile:output_type -> hostagent.v1.WriteFileResponse
|
||||
20, // 61: hostagent.v1.HostAgentService.ReadFile:output_type -> hostagent.v1.ReadFileResponse
|
||||
32, // 62: hostagent.v1.HostAgentService.ListDir:output_type -> hostagent.v1.ListDirResponse
|
||||
35, // 63: hostagent.v1.HostAgentService.MakeDir:output_type -> hostagent.v1.MakeDirResponse
|
||||
37, // 64: hostagent.v1.HostAgentService.RemovePath:output_type -> hostagent.v1.RemovePathResponse
|
||||
9, // 65: hostagent.v1.HostAgentService.CreateSnapshot:output_type -> hostagent.v1.CreateSnapshotResponse
|
||||
11, // 66: hostagent.v1.HostAgentService.DeleteSnapshot:output_type -> hostagent.v1.DeleteSnapshotResponse
|
||||
22, // 67: hostagent.v1.HostAgentService.ExecStream:output_type -> hostagent.v1.ExecStreamResponse
|
||||
28, // 68: hostagent.v1.HostAgentService.WriteFileStream:output_type -> hostagent.v1.WriteFileStreamResponse
|
||||
30, // 69: hostagent.v1.HostAgentService.ReadFileStream:output_type -> hostagent.v1.ReadFileStreamResponse
|
||||
39, // 70: hostagent.v1.HostAgentService.PingSandbox:output_type -> hostagent.v1.PingSandboxResponse
|
||||
41, // 71: hostagent.v1.HostAgentService.Terminate:output_type -> hostagent.v1.TerminateResponse
|
||||
44, // 72: hostagent.v1.HostAgentService.GetSandboxMetrics:output_type -> hostagent.v1.GetSandboxMetricsResponse
|
||||
46, // 73: hostagent.v1.HostAgentService.FlushSandboxMetrics:output_type -> hostagent.v1.FlushSandboxMetricsResponse
|
||||
48, // 74: hostagent.v1.HostAgentService.FlattenRootfs:output_type -> hostagent.v1.FlattenRootfsResponse
|
||||
50, // 75: hostagent.v1.HostAgentService.PtyAttach:output_type -> hostagent.v1.PtyAttachResponse
|
||||
55, // 76: hostagent.v1.HostAgentService.PtySendInput:output_type -> hostagent.v1.PtySendInputResponse
|
||||
57, // 77: hostagent.v1.HostAgentService.PtyResize:output_type -> hostagent.v1.PtyResizeResponse
|
||||
59, // 78: hostagent.v1.HostAgentService.PtyKill:output_type -> hostagent.v1.PtyKillResponse
|
||||
61, // 79: hostagent.v1.HostAgentService.StartBackground:output_type -> hostagent.v1.StartBackgroundResponse
|
||||
64, // 80: hostagent.v1.HostAgentService.ListProcesses:output_type -> hostagent.v1.ListProcessesResponse
|
||||
66, // 81: hostagent.v1.HostAgentService.KillProcess:output_type -> hostagent.v1.KillProcessResponse
|
||||
68, // 82: hostagent.v1.HostAgentService.ConnectProcess:output_type -> hostagent.v1.ConnectProcessResponse
|
||||
54, // [54:83] is the sub-list for method output_type
|
||||
25, // [25:54] is the sub-list for method input_type
|
||||
25, // [25:25] is the sub-list for extension type_name
|
||||
25, // [25:25] is the sub-list for extension extendee
|
||||
0, // [0:25] is the sub-list for field type_name
|
||||
73, // 4: hostagent.v1.ExecRequest.envs:type_name -> hostagent.v1.ExecRequest.EnvsEntry
|
||||
16, // 5: hostagent.v1.ListSandboxesResponse.sandboxes:type_name -> hostagent.v1.SandboxInfo
|
||||
74, // 6: hostagent.v1.SandboxInfo.metadata:type_name -> hostagent.v1.SandboxInfo.MetadataEntry
|
||||
23, // 7: hostagent.v1.ExecStreamResponse.start:type_name -> hostagent.v1.ExecStreamStart
|
||||
24, // 8: hostagent.v1.ExecStreamResponse.data:type_name -> hostagent.v1.ExecStreamData
|
||||
25, // 9: hostagent.v1.ExecStreamResponse.end:type_name -> hostagent.v1.ExecStreamEnd
|
||||
27, // 10: hostagent.v1.WriteFileStreamRequest.meta:type_name -> hostagent.v1.WriteFileStreamMeta
|
||||
33, // 11: hostagent.v1.ListDirResponse.entries:type_name -> hostagent.v1.FileEntry
|
||||
33, // 12: hostagent.v1.MakeDirResponse.entry:type_name -> hostagent.v1.FileEntry
|
||||
42, // 13: hostagent.v1.GetSandboxMetricsResponse.points:type_name -> hostagent.v1.MetricPoint
|
||||
42, // 14: hostagent.v1.FlushSandboxMetricsResponse.points_10m:type_name -> hostagent.v1.MetricPoint
|
||||
42, // 15: hostagent.v1.FlushSandboxMetricsResponse.points_2h:type_name -> hostagent.v1.MetricPoint
|
||||
42, // 16: hostagent.v1.FlushSandboxMetricsResponse.points_24h:type_name -> hostagent.v1.MetricPoint
|
||||
75, // 17: hostagent.v1.PtyAttachRequest.envs:type_name -> hostagent.v1.PtyAttachRequest.EnvsEntry
|
||||
51, // 18: hostagent.v1.PtyAttachResponse.started:type_name -> hostagent.v1.PtyStarted
|
||||
52, // 19: hostagent.v1.PtyAttachResponse.output:type_name -> hostagent.v1.PtyOutput
|
||||
53, // 20: hostagent.v1.PtyAttachResponse.exited:type_name -> hostagent.v1.PtyExited
|
||||
76, // 21: hostagent.v1.StartBackgroundRequest.envs:type_name -> hostagent.v1.StartBackgroundRequest.EnvsEntry
|
||||
63, // 22: hostagent.v1.ListProcessesResponse.processes:type_name -> hostagent.v1.ProcessEntry
|
||||
23, // 23: hostagent.v1.ConnectProcessResponse.start:type_name -> hostagent.v1.ExecStreamStart
|
||||
24, // 24: hostagent.v1.ConnectProcessResponse.data:type_name -> hostagent.v1.ExecStreamData
|
||||
25, // 25: hostagent.v1.ConnectProcessResponse.end:type_name -> hostagent.v1.ExecStreamEnd
|
||||
0, // 26: hostagent.v1.HostAgentService.CreateSandbox:input_type -> hostagent.v1.CreateSandboxRequest
|
||||
2, // 27: hostagent.v1.HostAgentService.DestroySandbox:input_type -> hostagent.v1.DestroySandboxRequest
|
||||
4, // 28: hostagent.v1.HostAgentService.PauseSandbox:input_type -> hostagent.v1.PauseSandboxRequest
|
||||
6, // 29: hostagent.v1.HostAgentService.ResumeSandbox:input_type -> hostagent.v1.ResumeSandboxRequest
|
||||
12, // 30: hostagent.v1.HostAgentService.Exec:input_type -> hostagent.v1.ExecRequest
|
||||
14, // 31: hostagent.v1.HostAgentService.ListSandboxes:input_type -> hostagent.v1.ListSandboxesRequest
|
||||
17, // 32: hostagent.v1.HostAgentService.WriteFile:input_type -> hostagent.v1.WriteFileRequest
|
||||
19, // 33: hostagent.v1.HostAgentService.ReadFile:input_type -> hostagent.v1.ReadFileRequest
|
||||
31, // 34: hostagent.v1.HostAgentService.ListDir:input_type -> hostagent.v1.ListDirRequest
|
||||
34, // 35: hostagent.v1.HostAgentService.MakeDir:input_type -> hostagent.v1.MakeDirRequest
|
||||
36, // 36: hostagent.v1.HostAgentService.RemovePath:input_type -> hostagent.v1.RemovePathRequest
|
||||
8, // 37: hostagent.v1.HostAgentService.CreateSnapshot:input_type -> hostagent.v1.CreateSnapshotRequest
|
||||
10, // 38: hostagent.v1.HostAgentService.DeleteSnapshot:input_type -> hostagent.v1.DeleteSnapshotRequest
|
||||
21, // 39: hostagent.v1.HostAgentService.ExecStream:input_type -> hostagent.v1.ExecStreamRequest
|
||||
26, // 40: hostagent.v1.HostAgentService.WriteFileStream:input_type -> hostagent.v1.WriteFileStreamRequest
|
||||
29, // 41: hostagent.v1.HostAgentService.ReadFileStream:input_type -> hostagent.v1.ReadFileStreamRequest
|
||||
38, // 42: hostagent.v1.HostAgentService.PingSandbox:input_type -> hostagent.v1.PingSandboxRequest
|
||||
40, // 43: hostagent.v1.HostAgentService.Terminate:input_type -> hostagent.v1.TerminateRequest
|
||||
43, // 44: hostagent.v1.HostAgentService.GetSandboxMetrics:input_type -> hostagent.v1.GetSandboxMetricsRequest
|
||||
45, // 45: hostagent.v1.HostAgentService.FlushSandboxMetrics:input_type -> hostagent.v1.FlushSandboxMetricsRequest
|
||||
47, // 46: hostagent.v1.HostAgentService.FlattenRootfs:input_type -> hostagent.v1.FlattenRootfsRequest
|
||||
49, // 47: hostagent.v1.HostAgentService.PtyAttach:input_type -> hostagent.v1.PtyAttachRequest
|
||||
54, // 48: hostagent.v1.HostAgentService.PtySendInput:input_type -> hostagent.v1.PtySendInputRequest
|
||||
56, // 49: hostagent.v1.HostAgentService.PtyResize:input_type -> hostagent.v1.PtyResizeRequest
|
||||
58, // 50: hostagent.v1.HostAgentService.PtyKill:input_type -> hostagent.v1.PtyKillRequest
|
||||
60, // 51: hostagent.v1.HostAgentService.StartBackground:input_type -> hostagent.v1.StartBackgroundRequest
|
||||
62, // 52: hostagent.v1.HostAgentService.ListProcesses:input_type -> hostagent.v1.ListProcessesRequest
|
||||
65, // 53: hostagent.v1.HostAgentService.KillProcess:input_type -> hostagent.v1.KillProcessRequest
|
||||
67, // 54: hostagent.v1.HostAgentService.ConnectProcess:input_type -> hostagent.v1.ConnectProcessRequest
|
||||
1, // 55: hostagent.v1.HostAgentService.CreateSandbox:output_type -> hostagent.v1.CreateSandboxResponse
|
||||
3, // 56: hostagent.v1.HostAgentService.DestroySandbox:output_type -> hostagent.v1.DestroySandboxResponse
|
||||
5, // 57: hostagent.v1.HostAgentService.PauseSandbox:output_type -> hostagent.v1.PauseSandboxResponse
|
||||
7, // 58: hostagent.v1.HostAgentService.ResumeSandbox:output_type -> hostagent.v1.ResumeSandboxResponse
|
||||
13, // 59: hostagent.v1.HostAgentService.Exec:output_type -> hostagent.v1.ExecResponse
|
||||
15, // 60: hostagent.v1.HostAgentService.ListSandboxes:output_type -> hostagent.v1.ListSandboxesResponse
|
||||
18, // 61: hostagent.v1.HostAgentService.WriteFile:output_type -> hostagent.v1.WriteFileResponse
|
||||
20, // 62: hostagent.v1.HostAgentService.ReadFile:output_type -> hostagent.v1.ReadFileResponse
|
||||
32, // 63: hostagent.v1.HostAgentService.ListDir:output_type -> hostagent.v1.ListDirResponse
|
||||
35, // 64: hostagent.v1.HostAgentService.MakeDir:output_type -> hostagent.v1.MakeDirResponse
|
||||
37, // 65: hostagent.v1.HostAgentService.RemovePath:output_type -> hostagent.v1.RemovePathResponse
|
||||
9, // 66: hostagent.v1.HostAgentService.CreateSnapshot:output_type -> hostagent.v1.CreateSnapshotResponse
|
||||
11, // 67: hostagent.v1.HostAgentService.DeleteSnapshot:output_type -> hostagent.v1.DeleteSnapshotResponse
|
||||
22, // 68: hostagent.v1.HostAgentService.ExecStream:output_type -> hostagent.v1.ExecStreamResponse
|
||||
28, // 69: hostagent.v1.HostAgentService.WriteFileStream:output_type -> hostagent.v1.WriteFileStreamResponse
|
||||
30, // 70: hostagent.v1.HostAgentService.ReadFileStream:output_type -> hostagent.v1.ReadFileStreamResponse
|
||||
39, // 71: hostagent.v1.HostAgentService.PingSandbox:output_type -> hostagent.v1.PingSandboxResponse
|
||||
41, // 72: hostagent.v1.HostAgentService.Terminate:output_type -> hostagent.v1.TerminateResponse
|
||||
44, // 73: hostagent.v1.HostAgentService.GetSandboxMetrics:output_type -> hostagent.v1.GetSandboxMetricsResponse
|
||||
46, // 74: hostagent.v1.HostAgentService.FlushSandboxMetrics:output_type -> hostagent.v1.FlushSandboxMetricsResponse
|
||||
48, // 75: hostagent.v1.HostAgentService.FlattenRootfs:output_type -> hostagent.v1.FlattenRootfsResponse
|
||||
50, // 76: hostagent.v1.HostAgentService.PtyAttach:output_type -> hostagent.v1.PtyAttachResponse
|
||||
55, // 77: hostagent.v1.HostAgentService.PtySendInput:output_type -> hostagent.v1.PtySendInputResponse
|
||||
57, // 78: hostagent.v1.HostAgentService.PtyResize:output_type -> hostagent.v1.PtyResizeResponse
|
||||
59, // 79: hostagent.v1.HostAgentService.PtyKill:output_type -> hostagent.v1.PtyKillResponse
|
||||
61, // 80: hostagent.v1.HostAgentService.StartBackground:output_type -> hostagent.v1.StartBackgroundResponse
|
||||
64, // 81: hostagent.v1.HostAgentService.ListProcesses:output_type -> hostagent.v1.ListProcessesResponse
|
||||
66, // 82: hostagent.v1.HostAgentService.KillProcess:output_type -> hostagent.v1.KillProcessResponse
|
||||
68, // 83: hostagent.v1.HostAgentService.ConnectProcess:output_type -> hostagent.v1.ConnectProcessResponse
|
||||
55, // [55:84] is the sub-list for method output_type
|
||||
26, // [26:55] is the sub-list for method input_type
|
||||
26, // [26:26] is the sub-list for extension type_name
|
||||
26, // [26:26] is the sub-list for extension extendee
|
||||
0, // [0:26] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_hostagent_proto_init() }
|
||||
@ -4699,7 +4724,7 @@ func file_hostagent_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_hostagent_proto_rawDesc), len(file_hostagent_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 76,
|
||||
NumMessages: 77,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
|
||||
@ -222,6 +222,10 @@ message ExecRequest {
|
||||
repeated string args = 3;
|
||||
// Timeout for the command in seconds (default: 30).
|
||||
int32 timeout_sec = 4;
|
||||
// Environment variables to set for the command.
|
||||
map<string, string> envs = 5;
|
||||
// Working directory for the command.
|
||||
string cwd = 6;
|
||||
}
|
||||
|
||||
message ExecResponse {
|
||||
|
||||
Reference in New Issue
Block a user