aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cni/87-podman-bridge.conflist4
-rwxr-xr-xhack/get_ci_vm.sh2
-rw-r--r--libpod/common_test.go1
-rw-r--r--libpod/container.go8
-rw-r--r--libpod/logs/log.go88
-rw-r--r--libpod/logs/reversereader/reversereader.go66
-rw-r--r--libpod/options.go3
-rw-r--r--libpod/runtime_pod_infra_linux.go2
-rw-r--r--libpod/util_test.go3
-rw-r--r--pkg/adapter/containers.go6
-rw-r--r--pkg/adapter/network.go1
-rw-r--r--pkg/api/handlers/images.go1
-rw-r--r--pkg/spec/createconfig.go3
-rw-r--r--pkg/specgen/create.go4
14 files changed, 145 insertions, 47 deletions
diff --git a/cni/87-podman-bridge.conflist b/cni/87-podman-bridge.conflist
index 39e79b13c..cd01b97ce 100644
--- a/cni/87-podman-bridge.conflist
+++ b/cni/87-podman-bridge.conflist
@@ -27,10 +27,6 @@
}
},
{
- "type": "firewall",
- "backend": "iptables"
- },
- {
"type": "tuning"
}
]
diff --git a/hack/get_ci_vm.sh b/hack/get_ci_vm.sh
index 22f902e2d..768137213 100755
--- a/hack/get_ci_vm.sh
+++ b/hack/get_ci_vm.sh
@@ -97,7 +97,7 @@ keys=[k for k in env if "ENCRYPTED" not in str(env[k])]
for k,v in env.items():
v=str(v)
if "ENCRYPTED" not in v:
- print "{0}=\"{1}\"".format(k, v),
+ print("{0}=\"{1}\"".format(k, v)),
'
}
diff --git a/libpod/common_test.go b/libpod/common_test.go
index 83b162c8a..63ea4f41b 100644
--- a/libpod/common_test.go
+++ b/libpod/common_test.go
@@ -23,7 +23,6 @@ func getTestContainer(id, name string, manager lock.Manager) (*Container, error)
Name: name,
RootfsImageID: id,
RootfsImageName: "testimg",
- ImageVolumes: true,
StaticDir: "/does/not/exist/",
LogPath: "/does/not/exist/",
Stdin: true,
diff --git a/libpod/container.go b/libpod/container.go
index 5e5c8ab26..dbd15e55f 100644
--- a/libpod/container.go
+++ b/libpod/container.go
@@ -249,8 +249,6 @@ type ContainerConfig struct {
RootfsImageName string `json:"rootfsImageName,omitempty"`
// Rootfs to use for the container, this conflicts with RootfsImageID
Rootfs string `json:"rootfs,omitempty"`
- // Whether to mount volumes specified in the image.
- ImageVolumes bool `json:"imageVolumes"`
// Src path to be mounted on /dev/shm in container.
ShmDir string `json:"ShmDir,omitempty"`
// Size of the container's SHM.
@@ -510,12 +508,6 @@ func (c *Container) Image() (string, string) {
return c.config.RootfsImageID, c.config.RootfsImageName
}
-// ImageVolumes returns whether the container is configured to create
-// persistent volumes requested by the image
-func (c *Container) ImageVolumes() bool {
- return c.config.ImageVolumes
-}
-
// ShmDir returns the sources path to be mounted on /dev/shm in container
func (c *Container) ShmDir() string {
return c.config.ShmDir
diff --git a/libpod/logs/log.go b/libpod/logs/log.go
index 9a7bcb5be..bd918abae 100644
--- a/libpod/logs/log.go
+++ b/libpod/logs/log.go
@@ -2,13 +2,16 @@ package logs
import (
"fmt"
- "io/ioutil"
+ "io"
+ "os"
"strings"
"sync"
"time"
+ "github.com/containers/libpod/libpod/logs/reversereader"
"github.com/hpcloud/tail"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
const (
@@ -74,43 +77,84 @@ func GetLogFile(path string, options *LogOptions) (*tail.Tail, []*LogLine, error
func getTailLog(path string, tail int) ([]*LogLine, error) {
var (
- tailLog []*LogLine
- nlls []*LogLine
- tailCounter int
- partial string
+ nlls []*LogLine
+ nllCounter int
+ leftover string
+ partial string
+ tailLog []*LogLine
)
- content, err := ioutil.ReadFile(path)
+ f, err := os.Open(path)
if err != nil {
return nil, err
}
- splitContent := strings.Split(string(content), "\n")
- // We read the content in reverse and add each nll until we have the same
- // number of F type messages as the desired tail
- for i := len(splitContent) - 1; i >= 0; i-- {
- if len(splitContent[i]) == 0 {
- continue
- }
- nll, err := NewLogLine(splitContent[i])
- if err != nil {
- return nil, err
+ rr, err := reversereader.NewReverseReader(f)
+ if err != nil {
+ return nil, err
+ }
+
+ inputs := make(chan []string)
+ go func() {
+ for {
+ s, err := rr.Read()
+ if err != nil {
+ if errors.Cause(err) == io.EOF {
+ inputs <- []string{leftover}
+ close(inputs)
+ break
+ }
+ logrus.Error(err)
+ close(inputs)
+ }
+ line := strings.Split(s+leftover, "\n")
+ if len(line) > 1 {
+ inputs <- line[1:]
+ }
+ leftover = line[0]
}
- nlls = append(nlls, nll)
- if !nll.Partial() {
- tailCounter++
+ }()
+
+ for i := range inputs {
+ // the incoming array is FIFO; we want FIFO so
+ // reverse the slice read order
+ for j := len(i) - 1; j >= 0; j-- {
+ // lines that are "" are junk
+ if len(i[j]) < 1 {
+ continue
+ }
+ // read the content in reverse and add each nll until we have the same
+ // number of F type messages as the desired tail
+ nll, err := NewLogLine(i[j])
+ if err != nil {
+ return nil, err
+ }
+ nlls = append(nlls, nll)
+ if !nll.Partial() {
+ nllCounter++
+ }
}
- if tailCounter == tail {
+ // if we have enough loglines, we can hangup
+ if nllCounter >= tail {
+ if err := f.Close(); err != nil {
+ logrus.Error(err)
+ }
break
}
}
- // Now we iterate the results and assemble partial messages to become full messages
+
+ // re-assemble the log lines and trim (if needed) to the
+ // tail length
for _, nll := range nlls {
if nll.Partial() {
partial += nll.Msg
} else {
nll.Msg += partial
- tailLog = append(tailLog, nll)
+ // prepend because we need to reverse the order again to FIFO
+ tailLog = append([]*LogLine{nll}, tailLog...)
partial = ""
}
+ if len(tailLog) == tail {
+ break
+ }
}
return tailLog, nil
}
diff --git a/libpod/logs/reversereader/reversereader.go b/libpod/logs/reversereader/reversereader.go
new file mode 100644
index 000000000..72d9ad975
--- /dev/null
+++ b/libpod/logs/reversereader/reversereader.go
@@ -0,0 +1,66 @@
+package reversereader
+
+import (
+ "io"
+ "os"
+
+ "github.com/pkg/errors"
+)
+
+// ReverseReader structure for reading a file backwards
+type ReverseReader struct {
+ reader *os.File
+ offset int64
+ readSize int64
+}
+
+// NewReverseReader returns a reader that reads from the end of a file
+// rather than the beginning. It sets the readsize to pagesize and determines
+// the first offset using using modulus.
+func NewReverseReader(reader *os.File) (*ReverseReader, error) {
+ // pagesize should be safe for memory use and file reads should be on page
+ // boundaries as well
+ pageSize := int64(os.Getpagesize())
+ stat, err := reader.Stat()
+ if err != nil {
+ return nil, err
+ }
+ // figure out the last page boundary
+ remainder := stat.Size() % pageSize
+ end, err := reader.Seek(0, 2)
+ if err != nil {
+ return nil, err
+ }
+ // set offset (starting position) to the last page boundary or
+ // zero if fits in one page
+ startOffset := end - remainder
+ if startOffset < 0 {
+ startOffset = 0
+ }
+ rr := ReverseReader{
+ reader: reader,
+ offset: startOffset,
+ readSize: pageSize,
+ }
+ return &rr, nil
+}
+
+// ReverseReader reads from a given offset to the previous offset and
+// then sets the newoff set one pagesize less than the previous read.
+func (r *ReverseReader) Read() (string, error) {
+ if r.offset < 0 {
+ return "", errors.Wrap(io.EOF, "at beginning of file")
+ }
+ // Read from given offset
+ b := make([]byte, r.readSize)
+ n, err := r.reader.ReadAt(b, r.offset)
+ if err != nil && errors.Cause(err) != io.EOF {
+ return "", err
+ }
+ if int64(n) < r.readSize {
+ b = b[0:n]
+ }
+ // Set to the next page boundary
+ r.offset = -r.readSize
+ return string(b), nil
+}
diff --git a/libpod/options.go b/libpod/options.go
index 1fd588867..d01e8a85f 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -593,7 +593,7 @@ func WithUser(user string) CtrCreateOption {
// other configuration from the image will be added to the config.
// TODO: Replace image name and ID with a libpod.Image struct when that is
// finished.
-func WithRootFSFromImage(imageID string, imageName string, useImageVolumes bool) CtrCreateOption {
+func WithRootFSFromImage(imageID string, imageName string) CtrCreateOption {
return func(ctr *Container) error {
if ctr.valid {
return define.ErrCtrFinalized
@@ -608,7 +608,6 @@ func WithRootFSFromImage(imageID string, imageName string, useImageVolumes bool)
ctr.config.RootfsImageID = imageID
ctr.config.RootfsImageName = imageName
- ctr.config.ImageVolumes = useImageVolumes
return nil
}
diff --git a/libpod/runtime_pod_infra_linux.go b/libpod/runtime_pod_infra_linux.go
index a6cac2b72..da46f03e8 100644
--- a/libpod/runtime_pod_infra_linux.go
+++ b/libpod/runtime_pod_infra_linux.go
@@ -127,7 +127,7 @@ func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, imgID
containerName := p.ID()[:IDTruncLength] + "-infra"
options = append(options, r.WithPod(p))
- options = append(options, WithRootFSFromImage(imgID, imgName, false))
+ options = append(options, WithRootFSFromImage(imgID, imgName))
options = append(options, WithName(containerName))
options = append(options, withIsInfra())
diff --git a/libpod/util_test.go b/libpod/util_test.go
index 70e989e1a..227686c2b 100644
--- a/libpod/util_test.go
+++ b/libpod/util_test.go
@@ -1,8 +1,9 @@
package libpod
import (
- "github.com/stretchr/testify/assert"
"testing"
+
+ "github.com/stretchr/testify/assert"
)
func TestRemoveScientificNotationFromFloat(t *testing.T) {
diff --git a/pkg/adapter/containers.go b/pkg/adapter/containers.go
index 170b2e24e..ab4255f89 100644
--- a/pkg/adapter/containers.go
+++ b/pkg/adapter/containers.go
@@ -338,7 +338,11 @@ func (r *LocalRuntime) Log(c *cliconfig.LogsValues, options *logs.LogOptions) er
if tailLen < 0 {
tailLen = 0
}
- logChannel := make(chan *logs.LogLine, tailLen*len(c.InputArgs)+1)
+ numContainers := len(c.InputArgs)
+ if numContainers == 0 {
+ numContainers = 1
+ }
+ logChannel := make(chan *logs.LogLine, tailLen*numContainers+1)
containers, err := shortcuts.GetContainersByContext(false, c.Latest, c.InputArgs, r.Runtime)
if err != nil {
return err
diff --git a/pkg/adapter/network.go b/pkg/adapter/network.go
index b25f54a13..c5bd91534 100644
--- a/pkg/adapter/network.go
+++ b/pkg/adapter/network.go
@@ -209,7 +209,6 @@ func (r *LocalRuntime) NetworkCreateBridge(cli *cliconfig.NetworkCreateValues) (
bridge := network.NewHostLocalBridge(bridgeDeviceName, isGateway, false, ipMasq, ipamConfig)
plugins = append(plugins, bridge)
plugins = append(plugins, network.NewPortMapPlugin())
- plugins = append(plugins, network.NewFirewallPlugin())
// if we find the dnsname plugin, we add configuration for it
if network.HasDNSNamePlugin(runtimeConfig.CNIPluginDir) && !cli.DisableDNS {
// Note: in the future we might like to allow for dynamic domain names
diff --git a/pkg/api/handlers/images.go b/pkg/api/handlers/images.go
index e4e394d68..96bcbdc96 100644
--- a/pkg/api/handlers/images.go
+++ b/pkg/api/handlers/images.go
@@ -156,6 +156,7 @@ func SearchImages(w http.ResponseWriter, r *http.Request) {
results, err := image.SearchImages(query.Term, options)
if err != nil {
utils.BadRequest(w, "term", query.Term, err)
+ return
}
utils.WriteResponse(w, http.StatusOK, results)
}
diff --git a/pkg/spec/createconfig.go b/pkg/spec/createconfig.go
index 5011df496..02678a687 100644
--- a/pkg/spec/createconfig.go
+++ b/pkg/spec/createconfig.go
@@ -341,9 +341,8 @@ func (c *CreateConfig) getContainerCreateOptions(runtime *libpod.Runtime, pod *l
}
options = append(options, nsOpts...)
- useImageVolumes := c.ImageVolumeType == TypeBind
// Gather up the options for NewContainer which consist of With... funcs
- options = append(options, libpod.WithRootFSFromImage(c.ImageID, c.Image, useImageVolumes))
+ options = append(options, libpod.WithRootFSFromImage(c.ImageID, c.Image))
options = append(options, libpod.WithConmonPidFile(c.ConmonPidFile))
options = append(options, libpod.WithLabels(c.Labels))
options = append(options, libpod.WithShmSize(c.Resources.ShmSize))
diff --git a/pkg/specgen/create.go b/pkg/specgen/create.go
index c8fee5f05..34f9ffac2 100644
--- a/pkg/specgen/create.go
+++ b/pkg/specgen/create.go
@@ -36,9 +36,7 @@ func (s *SpecGenerator) MakeContainer(rt *libpod.Runtime) (*libpod.Container, er
return nil, err
}
- // TODO mheon wants to talk with Dan about this
- useImageVolumes := s.ImageVolumeMode == "bind"
- options = append(options, libpod.WithRootFSFromImage(newImage.ID(), s.Image, useImageVolumes))
+ options = append(options, libpod.WithRootFSFromImage(newImage.ID(), s.Image))
runtimeSpec, err := s.toOCISpec(rt, newImage)
if err != nil {