server: fix PortForward panic

During "Port forwarding" e2e tests, the following panic happened:

```
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x64981d]

goroutine 52788 [running]:
panic(0x1830ee0, 0xc4200100c0)
        /usr/lib/golang/src/runtime/panic.go:500 +0x1a1
github.com/kubernetes-incubator/cri-o/oci.(*Runtime).UpdateStatus(0xc4202afc00,
0x0, 0x0, 0x0)
        /home/amurdaca/go/src/github.com/kubernetes-incubator/cri-o/oci/oci.go:549
+0x7d
github.com/kubernetes-incubator/cri-o/server.streamService.PortForward(0xc42026e000,
0x0, 0x0, 0x0, 0x0, 0xc420d9af40, 0x40, 0xc400000050, 0x7fe660659a28,
0xc4201cd0e0, ...)
```

The issue is `streamService.PortForward` assumed the first argument to
be the sandbox's infra container ID, thus trying to get it from memory
store using `.state.containers.Get`. Since that ID is of the sandbox
itself, it fails to get the container object from memory and panics in
`UpdateStatus`.

Fix it by looking for the sandbox's infra container ID starting from a
sandbox ID.

Signed-off-by: Antonio Murdaca <runcom@redhat.com>
This commit is contained in:
Antonio Murdaca 2017-05-28 17:22:46 +02:00
parent cf4e5ee903
commit 1e9ef65345
No known key found for this signature in database
GPG key ID: B2BEAD150DE936B9
2 changed files with 8 additions and 2 deletions

View file

@ -26,8 +26,8 @@ func (s *Server) PortForward(ctx context.Context, req *pb.PortForwardRequest) (*
return resp, nil
}
func (ss streamService) PortForward(podInfraContainerID string, port int32, stream io.ReadWriteCloser) error {
c := ss.runtimeServer.state.containers.Get(podInfraContainerID)
func (ss streamService) PortForward(podSandboxID string, port int32, stream io.ReadWriteCloser) error {
c := ss.runtimeServer.GetSandboxContainer(podSandboxID)
if err := ss.runtimeServer.runtime.UpdateStatus(c); err != nil {
return err

View file

@ -672,6 +672,12 @@ func (s *Server) getContainer(id string) *oci.Container {
return c
}
// GetSandboxContainer returns the infra container for a given sandbox
func (s *Server) GetSandboxContainer(id string) *oci.Container {
sb := s.getSandbox(id)
return sb.infraContainer
}
func (s *Server) removeContainer(c *oci.Container) {
s.stateLock.Lock()
sandbox := s.state.sandboxes[c.Sandbox()]