api: To watch the vm console in FetchSandbox api

When do sandbox release, the kataBuiltInProxy will
be closed, and it will stop the watch of vm's console;
Thus it needs to restart the proxy to monitor the vm
console once to restore the sandbox.

Fixes: #441

Signed-off-by: fupan <lifupan@gmail.com>
This commit is contained in:
fupan 2018-06-22 16:07:34 +08:00
parent 47caba8370
commit 9155412b24
12 changed files with 93 additions and 5 deletions

View File

@ -140,6 +140,9 @@ type agent interface {
// disconnect will disconnect the connection to the agent // disconnect will disconnect the connection to the agent
disconnect() error disconnect() error
// start the proxy
startProxy(sandbox *Sandbox) error
// createSandbox will tell the agent to perform necessary setup for a Sandbox. // createSandbox will tell the agent to perform necessary setup for a Sandbox.
createSandbox(sandbox *Sandbox) error createSandbox(sandbox *Sandbox) error

View File

@ -110,7 +110,21 @@ func FetchSandbox(sandboxID string) (VCSandbox, error) {
defer unlockSandbox(lockFile) defer unlockSandbox(lockFile)
// Fetch the sandbox from storage and create it. // 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. // StartSandbox is the virtcontainers sandbox starting entry point.

View File

@ -41,3 +41,8 @@ func (p *ccProxy) start(sandbox *Sandbox, params proxyParams) (int, string, erro
func (p *ccProxy) stop(sandbox *Sandbox, pid int) error { func (p *ccProxy) stop(sandbox *Sandbox, pid int) error {
return nil return nil
} }
// The ccproxy doesn't need to watch the vm console, thus return false always.
func (p *ccProxy) consoleWatched() bool {
return false
}

View File

@ -340,8 +340,11 @@ func (h *hyper) exec(sandbox *Sandbox, c Container, cmd Cmd) (*Process, error) {
return process, nil return process, nil
} }
// startSandbox is the agent Sandbox starting implementation for hyperstart. func (h *hyper) startProxy(sandbox *Sandbox) error {
func (h *hyper) startSandbox(sandbox *Sandbox) error { if h.proxy.consoleWatched() {
return nil
}
// Start the proxy here // Start the proxy here
pid, uri, err := h.proxy.start(sandbox, proxyParams{}) pid, uri, err := h.proxy.start(sandbox, proxyParams{})
if err != nil { if err != nil {
@ -357,6 +360,17 @@ func (h *hyper) startSandbox(sandbox *Sandbox) error {
h.Logger().WithField("proxy-pid", pid).Info("proxy started") 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 { if err := h.register(); err != nil {
return err return err
} }

View File

@ -419,11 +419,15 @@ func (k *kataAgent) generateInterfacesAndRoutes(networkNS NetworkNamespace) ([]*
return ifaces, routes, nil return ifaces, routes, nil
} }
func (k *kataAgent) startSandbox(sandbox *Sandbox) error { func (k *kataAgent) startProxy(sandbox *Sandbox) error {
if k.proxy == nil { if k.proxy == nil {
return errorMissingProxy return errorMissingProxy
} }
if k.proxy.consoleWatched() {
return nil
}
// Get agent socket path to provide it to the proxy. // Get agent socket path to provide it to the proxy.
agentURL, err := k.agentURL() agentURL, err := k.agentURL()
if err != nil { if err != nil {
@ -454,6 +458,15 @@ func (k *kataAgent) startSandbox(sandbox *Sandbox) error {
"proxy-url": uri, "proxy-url": uri,
}).Info("proxy started") }).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 hostname := sandbox.config.Hostname
if len(hostname) > maxHostnameLen { if len(hostname) > maxHostnameLen {
hostname = hostname[:maxHostnameLen] hostname = hostname[:maxHostnameLen]

View File

@ -21,11 +21,16 @@ type kataBuiltInProxy struct {
conn net.Conn 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. // start is the proxy start implementation for kata builtin proxy.
// It starts the console watcher for the guest. // It starts the console watcher for the guest.
// It returns agentURL to let agent connect directly. // It returns agentURL to let agent connect directly.
func (p *kataBuiltInProxy) start(sandbox *Sandbox, params proxyParams) (int, string, error) { 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) return -1, "", fmt.Errorf("kata builtin proxy running for sandbox %s", p.sandboxID)
} }

View File

@ -17,6 +17,11 @@ import (
type kataProxy struct { 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. // start is kataProxy start implementation for proxy interface.
func (p *kataProxy) start(sandbox *Sandbox, params proxyParams) (int, string, error) { func (p *kataProxy) start(sandbox *Sandbox, params proxyParams) (int, string, error) {
if sandbox.agent == nil { if sandbox.agent == nil {

View File

@ -35,3 +35,8 @@ func (p *noProxy) start(sandbox *Sandbox, params proxyParams) (int, string, erro
func (p *noProxy) stop(sandbox *Sandbox, pid int) error { func (p *noProxy) stop(sandbox *Sandbox, pid int) error {
return nil return nil
} }
// The noproxy doesn't need to watch the vm console, thus return false always.
func (p *noProxy) consoleWatched() bool {
return false
}

View File

@ -16,6 +16,11 @@ import (
type noopAgent struct { 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. // init initializes the Noop agent, i.e. it does nothing.
func (n *noopAgent) init(sandbox *Sandbox, config interface{}) error { func (n *noopAgent) init(sandbox *Sandbox, config interface{}) error {
return nil return nil

View File

@ -22,3 +22,8 @@ func (p *noopProxy) start(sandbox *Sandbox, params proxyParams) (int, string, er
func (p *noopProxy) stop(sandbox *Sandbox, pid int) error { func (p *noopProxy) stop(sandbox *Sandbox, pid int) error {
return nil return nil
} }
// The noopproxy doesn't need to watch the vm console, thus return false always.
func (p *noopProxy) consoleWatched() bool {
return false
}

View File

@ -170,4 +170,7 @@ type proxy interface {
// stop terminates a proxy instance after all communications with the // stop terminates a proxy instance after all communications with the
// agent inside the VM have been properly stopped. // agent inside the VM have been properly stopped.
stop(sandbox *Sandbox, pid int) error stop(sandbox *Sandbox, pid int) error
//check if the proxy has watched the vm console.
consoleWatched() bool
} }

View File

@ -352,6 +352,17 @@ type SandboxConfig struct {
SharePidNs bool 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. // valid checks that the sandbox configuration is valid.
func (sandboxConfig *SandboxConfig) valid() bool { func (sandboxConfig *SandboxConfig) valid() bool {
if sandboxConfig.ID == "" { if sandboxConfig.ID == "" {