Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .cirrus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -292,12 +292,14 @@ testing_task:
setup_environment_script: '$SCRIPT_BASE/setup_environment.sh |& ${TIMESTAMP}'
unit_test_script: '$SCRIPT_BASE/unit_test.sh |& ${TIMESTAMP}'
integration_test_script: '$SCRIPT_BASE/integration_test.sh |& ${TIMESTAMP}'
ginkgo_node_logs_script: 'cat $CIRRUS_WORKING_DIR/test/e2e/ginkgo-node-*.log || echo "Ginkgo node logs not found"'
audit_log_script: 'cat /var/log/audit/audit.log || cat /var/log/kern.log'
journalctl_b_script: 'journalctl -b'

on_failure:
failed_master_script: '$CIRRUS_WORKING_DIR/$SCRIPT_BASE/notice_master_failure.sh'
# Job has already failed, don't fail again and miss collecting data
failed_ginkgo_node_logs_script: 'cat $CIRRUS_WORKING_DIR/test/e2e/ginkgo-node-*.log || echo "Ginkgo node logs not found"'
failed_audit_log_script: 'cat /var/log/audit/audit.log || cat /var/log/kern.log || echo "Uh oh, cat audit.log failed"'
failed_journalctl_b_script: 'journalctl -b || echo "Uh oh, journalctl -b failed"'

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ localunit: test/goecho/goecho varlink_generate
./contrib/cirrus/lib.sh.t

ginkgo:
ginkgo -v -tags "$(BUILDTAGS)" $(GINKGOTIMEOUT) -cover -flakeAttempts 3 -progress -trace -noColor -nodes 3 test/e2e/.
ginkgo -v -tags "$(BUILDTAGS)" $(GINKGOTIMEOUT) -cover -flakeAttempts 3 -progress -trace -noColor -nodes 3 -debug test/e2e/.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does not look like this should be merged.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vrothberg this option is needed with -nodes 3 to make ginkgo log output from each node. Otherwise, if any node hangs for any reason, it's incredibly difficult to debug which test caused the problem.

Copy link
Member

@vrothberg vrothberg May 15, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, that sounds important. The commit message mentions not to merge it, so we might need to change the message to avoid confusion.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initially we just wanted it for debug, so I added the quick "HACK" message. Changed now.


ginkgo-remote:
ginkgo -v -tags "$(BUILDTAGS) remoteclient" $(GINKGOTIMEOUT) -cover -flakeAttempts 3 -progress -trace -noColor test/e2e/.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, we might want to consider adding -debug here as well.

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ popularized by Kubernetes. Libpod also contains the Pod Manager tool `(Podman)`

## Overview and scope

At a high level, the scope of libpod and podman is the following:
At a high level, the scope of libpod and Podman is the following:

* Support multiple image formats including the OCI and Docker image formats.
* Support for multiple means to download images including trust & image verification.
Expand Down
12 changes: 10 additions & 2 deletions libpod/container_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"io/ioutil"
"os"
"strconv"
"sync"
"time"

"github.com/containers/libpod/libpod/driver"
Expand Down Expand Up @@ -119,13 +120,20 @@ func (c *Container) StartAndAttach(ctx context.Context, streams *AttachStreams,

attachChan := make(chan error)

// We need to ensure that we don't return until start() fired in attach.
// Use a WaitGroup to sync this.
wg := new(sync.WaitGroup)
wg.Add(1)

// Attach to the container before starting it
go func() {
if err := c.attach(streams, keys, resize, true); err != nil {
if err := c.attach(streams, keys, resize, true, wg); err != nil {
attachChan <- err
}
close(attachChan)
}()

wg.Wait()
c.newContainerEvent(events.Attach)
return attachChan, nil
}
Expand Down Expand Up @@ -398,7 +406,7 @@ func (c *Container) Attach(streams *AttachStreams, keys string, resize <-chan re
return errors.Wrapf(ErrCtrStateInvalid, "can only attach to created or running containers")
}
defer c.newContainerEvent(events.Attach)
return c.attach(streams, keys, resize, false)
return c.attach(streams, keys, resize, false, nil)
}

// Mount mounts a container's filesystem on the host
Expand Down
17 changes: 13 additions & 4 deletions libpod/container_attach_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"net"
"os"
"path/filepath"
"sync"

"github.com/containers/libpod/pkg/kubeutils"
"github.com/containers/libpod/utils"
Expand All @@ -31,7 +32,7 @@ const (

// Attach to the given container
// Does not check if state is appropriate
func (c *Container) attach(streams *AttachStreams, keys string, resize <-chan remotecommand.TerminalSize, startContainer bool) error {
func (c *Container) attach(streams *AttachStreams, keys string, resize <-chan remotecommand.TerminalSize, startContainer bool, wg *sync.WaitGroup) error {
if !streams.AttachOutput && !streams.AttachError && !streams.AttachInput {
return errors.Wrapf(ErrInvalidArg, "must provide at least one stream to attach to")
}
Expand All @@ -48,12 +49,17 @@ func (c *Container) attach(streams *AttachStreams, keys string, resize <-chan re

logrus.Debugf("Attaching to container %s", c.ID())

return c.attachContainerSocket(resize, detachKeys, streams, startContainer)
return c.attachContainerSocket(resize, detachKeys, streams, startContainer, wg)
}

// attachContainerSocket connects to the container's attach socket and deals with the IO
// attachContainerSocket connects to the container's attach socket and deals with the IO.
// wg is only required if startContainer is true
// TODO add a channel to allow interrupting
func (c *Container) attachContainerSocket(resize <-chan remotecommand.TerminalSize, detachKeys []byte, streams *AttachStreams, startContainer bool) error {
func (c *Container) attachContainerSocket(resize <-chan remotecommand.TerminalSize, detachKeys []byte, streams *AttachStreams, startContainer bool, wg *sync.WaitGroup) error {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Can we use a Mutex instead of a WaitGroup? The WaitGroup implies that we are waiting for multiple tasks to finish which does not seem to be the case.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On looking into this more: I'd prefer to stick with a WG - it's a lot more clear what's going on than with a mutex (Why am I unlocking this mutex inside of attachContainerSocket()? What locked it in the first place?). The control flow here is already complicated enough (took four hours to zero in on this bug) and I'd prefer not to make it any more so.

if startContainer && wg == nil {
return errors.Wrapf(ErrInternal, "wait group not passed when startContainer set")
}

kubeutils.HandleResizing(resize, func(size remotecommand.TerminalSize) {
controlPath := filepath.Join(c.bundlePath(), "ctl")
controlFile, err := os.OpenFile(controlPath, unix.O_WRONLY, 0)
Expand Down Expand Up @@ -84,10 +90,13 @@ func (c *Container) attachContainerSocket(resize <-chan remotecommand.TerminalSi
}
defer conn.Close()

// If starting was requested, start the container and notify when that's
// done.
if startContainer {
if err := c.start(); err != nil {
return err
}
wg.Done()
}

receiveStdoutError := make(chan error)
Expand Down
4 changes: 3 additions & 1 deletion libpod/container_attach_unsupported.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
package libpod

import (
"sync"

"k8s.io/client-go/tools/remotecommand"
)

func (c *Container) attach(streams *AttachStreams, keys string, resize <-chan remotecommand.TerminalSize, startContainer bool) error {
func (c *Container) attach(streams *AttachStreams, keys string, resize <-chan remotecommand.TerminalSize, startContainer bool, wg *sync.WaitGroup) error {
return ErrNotImplemented
}
37 changes: 10 additions & 27 deletions test/e2e/cp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,11 @@ var _ = Describe("Podman cp", func() {

It("podman cp file", func() {
path, err := os.Getwd()
if err != nil {
os.Exit(1)
}
Expect(err).To(BeNil())
filePath := filepath.Join(path, "cp_test.txt")
fromHostToContainer := []byte("copy from host to container")
err = ioutil.WriteFile(filePath, fromHostToContainer, 0644)
if err != nil {
os.Exit(1)
}
Expect(err).To(BeNil())

session := podmanTest.Podman([]string{"create", ALPINE, "cat", "foo"})
session.WaitWithDefaultTimeout()
Expand All @@ -69,15 +65,12 @@ var _ = Describe("Podman cp", func() {

It("podman cp file to dir", func() {
path, err := os.Getwd()
if err != nil {
os.Exit(1)
}
Expect(err).To(BeNil())
filePath := filepath.Join(path, "cp_test.txt")
fromHostToContainer := []byte("copy from host to container directory")
err = ioutil.WriteFile(filePath, fromHostToContainer, 0644)
if err != nil {
os.Exit(1)
}
Expect(err).To(BeNil())

session := podmanTest.Podman([]string{"create", ALPINE, "ls", "foodir/"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expand All @@ -97,14 +90,10 @@ var _ = Describe("Podman cp", func() {

It("podman cp dir to dir", func() {
path, err := os.Getwd()
if err != nil {
os.Exit(1)
}
Expect(err).To(BeNil())
testDirPath := filepath.Join(path, "TestDir")
err = os.Mkdir(testDirPath, 0777)
if err != nil {
os.Exit(1)
}
Expect(err).To(BeNil())

session := podmanTest.Podman([]string{"create", ALPINE, "ls", "/foodir"})
session.WaitWithDefaultTimeout()
Expand All @@ -124,19 +113,13 @@ var _ = Describe("Podman cp", func() {

It("podman cp stdin/stdout", func() {
path, err := os.Getwd()
if err != nil {
os.Exit(1)
}
Expect(err).To(BeNil())
testDirPath := filepath.Join(path, "TestDir")
err = os.Mkdir(testDirPath, 0777)
if err != nil {
os.Exit(1)
}
Expect(err).To(BeNil())
cmd := exec.Command("tar", "-zcvf", "file.tar.gz", testDirPath)
_, err = cmd.Output()
if err != nil {
os.Exit(1)
}
Expect(err).To(BeNil())

session := podmanTest.Podman([]string{"create", ALPINE, "ls", "foo"})
session.WaitWithDefaultTimeout()
Expand Down