diff --git a/virtcontainers/agent.go b/virtcontainers/agent.go index 0f32e9d03c..c65406e455 100644 --- a/virtcontainers/agent.go +++ b/virtcontainers/agent.go @@ -140,6 +140,9 @@ type agent interface { // disconnect will disconnect the connection to the agent disconnect() error + // start the proxy + startProxy(sandbox *Sandbox) error + // createSandbox will tell the agent to perform necessary setup for a Sandbox. createSandbox(sandbox *Sandbox) error diff --git a/virtcontainers/api.go b/virtcontainers/api.go index b91c8812f2..dfaf0c881a 100644 --- a/virtcontainers/api.go +++ b/virtcontainers/api.go @@ -110,7 +110,21 @@ func FetchSandbox(sandboxID string) (VCSandbox, error) { defer unlockSandbox(lockFile) // Fetch the sandbox from storage and create it. - return fetchSandbox(sandboxID) + sandbox, err := fetchSandbox(sandboxID) + if err != nil { + return nil, err + } + + // If the proxy is KataBuiltInProxyType type, it needs to restart the proxy to watch the + // guest console if it hadn't been watched. + if isProxyBuiltIn(sandbox.config.ProxyType) { + err = sandbox.startProxy() + if err != nil { + return nil, err + } + } + + return sandbox, nil } // StartSandbox is the virtcontainers sandbox starting entry point. diff --git a/virtcontainers/cc_proxy.go b/virtcontainers/cc_proxy.go index 7cdedd776b..ef6cce5eb0 100644 --- a/virtcontainers/cc_proxy.go +++ b/virtcontainers/cc_proxy.go @@ -41,3 +41,8 @@ func (p *ccProxy) start(sandbox *Sandbox, params proxyParams) (int, string, erro func (p *ccProxy) stop(sandbox *Sandbox, pid int) error { return nil } + +// The ccproxy doesn't need to watch the vm console, thus return false always. +func (p *ccProxy) consoleWatched() bool { + return false +} diff --git a/virtcontainers/hyperstart_agent.go b/virtcontainers/hyperstart_agent.go index 4669930a2c..6c08b706a4 100644 --- a/virtcontainers/hyperstart_agent.go +++ b/virtcontainers/hyperstart_agent.go @@ -340,8 +340,11 @@ func (h *hyper) exec(sandbox *Sandbox, c Container, cmd Cmd) (*Process, error) { return process, nil } -// startSandbox is the agent Sandbox starting implementation for hyperstart. -func (h *hyper) startSandbox(sandbox *Sandbox) error { +func (h *hyper) startProxy(sandbox *Sandbox) error { + if h.proxy.consoleWatched() { + return nil + } + // Start the proxy here pid, uri, err := h.proxy.start(sandbox, proxyParams{}) if err != nil { @@ -357,6 +360,17 @@ func (h *hyper) startSandbox(sandbox *Sandbox) error { h.Logger().WithField("proxy-pid", pid).Info("proxy started") + return nil +} + +// startSandbox is the agent Sandbox starting implementation for hyperstart. +func (h *hyper) startSandbox(sandbox *Sandbox) error { + + err := h.startProxy(sandbox) + if err != nil { + return err + } + if err := h.register(); err != nil { return err } diff --git a/virtcontainers/kata_agent.go b/virtcontainers/kata_agent.go index 3167bc5ab3..9bb5c796dd 100644 --- a/virtcontainers/kata_agent.go +++ b/virtcontainers/kata_agent.go @@ -419,11 +419,15 @@ func (k *kataAgent) generateInterfacesAndRoutes(networkNS NetworkNamespace) ([]* return ifaces, routes, nil } -func (k *kataAgent) startSandbox(sandbox *Sandbox) error { +func (k *kataAgent) startProxy(sandbox *Sandbox) error { if k.proxy == nil { return errorMissingProxy } + if k.proxy.consoleWatched() { + return nil + } + // Get agent socket path to provide it to the proxy. agentURL, err := k.agentURL() if err != nil { @@ -454,6 +458,15 @@ func (k *kataAgent) startSandbox(sandbox *Sandbox) error { "proxy-url": uri, }).Info("proxy started") + return nil +} + +func (k *kataAgent) startSandbox(sandbox *Sandbox) error { + err := k.startProxy(sandbox) + if err != nil { + return err + } + hostname := sandbox.config.Hostname if len(hostname) > maxHostnameLen { hostname = hostname[:maxHostnameLen] diff --git a/virtcontainers/kata_builtin_proxy.go b/virtcontainers/kata_builtin_proxy.go index f5f67743b0..3ab80c934c 100644 --- a/virtcontainers/kata_builtin_proxy.go +++ b/virtcontainers/kata_builtin_proxy.go @@ -21,11 +21,16 @@ type kataBuiltInProxy struct { conn net.Conn } +// check if the proxy has watched the vm console. +func (p *kataBuiltInProxy) consoleWatched() bool { + return p.conn != nil +} + // start is the proxy start implementation for kata builtin proxy. // It starts the console watcher for the guest. // It returns agentURL to let agent connect directly. func (p *kataBuiltInProxy) start(sandbox *Sandbox, params proxyParams) (int, string, error) { - if p.conn != nil { + if p.consoleWatched() { return -1, "", fmt.Errorf("kata builtin proxy running for sandbox %s", p.sandboxID) } diff --git a/virtcontainers/kata_proxy.go b/virtcontainers/kata_proxy.go index 608b1d6f0d..5d996e7ead 100644 --- a/virtcontainers/kata_proxy.go +++ b/virtcontainers/kata_proxy.go @@ -17,6 +17,11 @@ import ( type kataProxy struct { } +// The kata proxy doesn't need to watch the vm console, thus return false always. +func (p *kataProxy) consoleWatched() bool { + return false +} + // start is kataProxy start implementation for proxy interface. func (p *kataProxy) start(sandbox *Sandbox, params proxyParams) (int, string, error) { if sandbox.agent == nil { diff --git a/virtcontainers/no_proxy.go b/virtcontainers/no_proxy.go index 520afbbafe..a3e9d0b78a 100644 --- a/virtcontainers/no_proxy.go +++ b/virtcontainers/no_proxy.go @@ -35,3 +35,8 @@ func (p *noProxy) start(sandbox *Sandbox, params proxyParams) (int, string, erro func (p *noProxy) stop(sandbox *Sandbox, pid int) error { return nil } + +// The noproxy doesn't need to watch the vm console, thus return false always. +func (p *noProxy) consoleWatched() bool { + return false +} diff --git a/virtcontainers/noop_agent.go b/virtcontainers/noop_agent.go index 57dc0e6da1..ed8abdbc75 100644 --- a/virtcontainers/noop_agent.go +++ b/virtcontainers/noop_agent.go @@ -16,6 +16,11 @@ import ( type noopAgent struct { } +//start the proxy to watch the vm console. It does nothing. +func (n *noopAgent) startProxy(sandbox *Sandbox) error { + return nil +} + // init initializes the Noop agent, i.e. it does nothing. func (n *noopAgent) init(sandbox *Sandbox, config interface{}) error { return nil diff --git a/virtcontainers/noop_proxy.go b/virtcontainers/noop_proxy.go index 1142875dd1..473d8a63ae 100644 --- a/virtcontainers/noop_proxy.go +++ b/virtcontainers/noop_proxy.go @@ -22,3 +22,8 @@ func (p *noopProxy) start(sandbox *Sandbox, params proxyParams) (int, string, er func (p *noopProxy) stop(sandbox *Sandbox, pid int) error { return nil } + +// The noopproxy doesn't need to watch the vm console, thus return false always. +func (p *noopProxy) consoleWatched() bool { + return false +} diff --git a/virtcontainers/proxy.go b/virtcontainers/proxy.go index 0d5886b830..4af852254f 100644 --- a/virtcontainers/proxy.go +++ b/virtcontainers/proxy.go @@ -170,4 +170,7 @@ type proxy interface { // stop terminates a proxy instance after all communications with the // agent inside the VM have been properly stopped. stop(sandbox *Sandbox, pid int) error + + //check if the proxy has watched the vm console. + consoleWatched() bool } diff --git a/virtcontainers/sandbox.go b/virtcontainers/sandbox.go index 776c0c102e..87f8eda529 100644 --- a/virtcontainers/sandbox.go +++ b/virtcontainers/sandbox.go @@ -352,6 +352,17 @@ type SandboxConfig struct { SharePidNs bool } +func (s *Sandbox) startProxy() error { + + // If the proxy is KataBuiltInProxyType type, it needs to restart the proxy + // to watch the guest console if it hadn't been watched. + if s.agent == nil { + return fmt.Errorf("sandbox %s missed agent pointer", s.ID()) + } + + return s.agent.startProxy(s) +} + // valid checks that the sandbox configuration is valid. func (sandboxConfig *SandboxConfig) valid() bool { if sandboxConfig.ID == "" {