diff --git a/virtcontainers/api.go b/virtcontainers/api.go index 52ceb55ca..21d05a6c6 100644 --- a/virtcontainers/api.go +++ b/virtcontainers/api.go @@ -44,6 +44,8 @@ func CreateSandbox(sandboxConfig SandboxConfig, factory Factory) (VCSandbox, err } func createSandboxFromConfig(sandboxConfig SandboxConfig, factory Factory) (*Sandbox, error) { + var err error + // Create the sandbox. s, err := createSandbox(sandboxConfig, factory) if err != nil { @@ -51,22 +53,50 @@ func createSandboxFromConfig(sandboxConfig SandboxConfig, factory Factory) (*San } // Create the sandbox network - if err := s.createNetwork(); err != nil { + if err = s.createNetwork(); err != nil { return nil, err } + // network rollback + defer func() { + if err != nil && s.networkNS.NetNsCreated { + s.removeNetwork() + } + }() + // Start the VM - if err := s.startVM(); err != nil { + if err = s.startVM(); err != nil { return nil, err } + // rollback to stop VM if error occurs + defer func() { + if err != nil { + s.stopVM() + } + }() + + // Once startVM is done, we want to guarantee + // that the sandbox is manageable. For that we need + // to start the sandbox inside the VM. + if err = s.agent.startSandbox(s); err != nil { + return nil, err + } + + // rollback to stop sandbox in VM + defer func() { + if err != nil { + s.agent.stopSandbox(s) + } + }() + // Create Containers - if err := s.createContainers(); err != nil { + if err = s.createContainers(); err != nil { return nil, err } // The sandbox is completely created now, we can store it. - if err := s.storeSandbox(); err != nil { + if err = s.storeSandbox(); err != nil { return nil, err } diff --git a/virtcontainers/kata_agent.go b/virtcontainers/kata_agent.go index 53559ca90..831862af2 100644 --- a/virtcontainers/kata_agent.go +++ b/virtcontainers/kata_agent.go @@ -450,6 +450,8 @@ func (k *kataAgent) generateInterfacesAndRoutes(networkNS NetworkNamespace) ([]* } func (k *kataAgent) startProxy(sandbox *Sandbox) error { + var err error + if k.proxy == nil { return errorMissingProxy } @@ -475,10 +477,18 @@ func (k *kataAgent) startProxy(sandbox *Sandbox) error { return err } + // If error occurs after kata-proxy process start, + // then rollback to kill kata-proxy process + defer func() { + if err != nil && pid > 0 { + k.proxy.stop(sandbox, pid) + } + }() + // Fill agent state with proxy information, and store them. k.state.ProxyPid = pid k.state.URL = uri - if err := sandbox.storage.storeAgentState(sandbox.id, k.state); err != nil { + if err = sandbox.storage.storeAgentState(sandbox.id, k.state); err != nil { return err } @@ -502,6 +512,11 @@ func (k *kataAgent) startSandbox(sandbox *Sandbox) error { hostname = hostname[:maxHostnameLen] } + // check grpc server is serving + if err = k.check(); err != nil { + return err + } + // // Setup network interfaces and routes // diff --git a/virtcontainers/sandbox.go b/virtcontainers/sandbox.go index 102e34a89..b3f5f0871 100644 --- a/virtcontainers/sandbox.go +++ b/virtcontainers/sandbox.go @@ -988,10 +988,12 @@ func (s *Sandbox) startVM() error { s.Logger().Info("VM started") - // Once startVM is done, we want to guarantee - // that the sandbox is manageable. For that we need - // to start the sandbox inside the VM. - return s.agent.startSandbox(s) + return nil +} + +// stopVM: stop the sandbox's VM +func (s *Sandbox) stopVM() error { + return s.hypervisor.stopSandbox() } func (s *Sandbox) addContainer(c *Container) error {