summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/api/handlers/compat/events.go6
-rw-r--r--pkg/api/handlers/compat/networks.go2
-rw-r--r--pkg/api/handlers/libpod/volumes.go30
-rw-r--r--pkg/api/server/server.go4
-rw-r--r--pkg/domain/infra/abi/containers.go4
-rw-r--r--pkg/domain/infra/abi/events.go2
-rw-r--r--pkg/domain/infra/abi/pods.go36
-rw-r--r--pkg/domain/infra/abi/volumes.go26
-rw-r--r--pkg/spec/createconfig.go9
-rw-r--r--pkg/specgen/generate/oci.go20
-rw-r--r--pkg/specgen/generate/ports.go112
-rw-r--r--pkg/specgen/specgen.go3
-rw-r--r--pkg/systemd/generate/common.go5
-rw-r--r--pkg/systemd/generate/common_test.go9
-rw-r--r--pkg/terminal/console_unix.go8
-rw-r--r--pkg/terminal/console_windows.go37
-rw-r--r--pkg/varlinkapi/attach.go3
-rw-r--r--pkg/varlinkapi/events.go3
18 files changed, 252 insertions, 67 deletions
diff --git a/pkg/api/handlers/compat/events.go b/pkg/api/handlers/compat/events.go
index 215d7c972..5acc94153 100644
--- a/pkg/api/handlers/compat/events.go
+++ b/pkg/api/handlers/compat/events.go
@@ -1,6 +1,7 @@
package compat
import (
+ "context"
"fmt"
"net/http"
@@ -45,13 +46,15 @@ func GetEvents(w http.ResponseWriter, r *http.Request) {
fromStart = true
}
+ eventCtx, eventCancel := context.WithCancel(r.Context())
eventChannel := make(chan *events.Event)
go func() {
readOpts := events.ReadOptions{FromStart: fromStart, Stream: query.Stream, Filters: libpodFilters, EventChannel: eventChannel, Since: query.Since, Until: query.Until}
- eventsError = runtime.Events(readOpts)
+ eventsError = runtime.Events(eventCtx, readOpts)
}()
if eventsError != nil {
utils.InternalServerError(w, eventsError)
+ eventCancel()
close(eventChannel)
return
}
@@ -59,6 +62,7 @@ func GetEvents(w http.ResponseWriter, r *http.Request) {
// If client disappears we need to stop listening for events
go func(done <-chan struct{}) {
<-done
+ eventCancel()
if _, ok := <-eventChannel; ok {
close(eventChannel)
}
diff --git a/pkg/api/handlers/compat/networks.go b/pkg/api/handlers/compat/networks.go
index fe7d8888e..2e11c0edb 100644
--- a/pkg/api/handlers/compat/networks.go
+++ b/pkg/api/handlers/compat/networks.go
@@ -285,7 +285,7 @@ func RemoveNetwork(w http.ResponseWriter, r *http.Request) {
return
}
if !exists {
- utils.Error(w, "network not found", http.StatusNotFound, err)
+ utils.Error(w, "network not found", http.StatusNotFound, network.ErrNetworkNotFound)
return
}
if err := network.RemoveNetwork(config, name); err != nil {
diff --git a/pkg/api/handlers/libpod/volumes.go b/pkg/api/handlers/libpod/volumes.go
index f9a651c5d..0d83218e3 100644
--- a/pkg/api/handlers/libpod/volumes.go
+++ b/pkg/api/handlers/libpod/volumes.go
@@ -86,6 +86,17 @@ func InspectVolume(w http.ResponseWriter, r *http.Request) {
utils.VolumeNotFound(w, name, err)
return
}
+ var uid, gid int
+ uid, err = vol.UID()
+ if err != nil {
+ utils.Error(w, "Error fetching volume UID", http.StatusInternalServerError, err)
+ return
+ }
+ gid, err = vol.GID()
+ if err != nil {
+ utils.Error(w, "Error fetching volume GID", http.StatusInternalServerError, err)
+ return
+ }
volResponse := entities.VolumeConfigResponse{
Name: vol.Name(),
Driver: vol.Driver(),
@@ -94,8 +105,8 @@ func InspectVolume(w http.ResponseWriter, r *http.Request) {
Labels: vol.Labels(),
Scope: vol.Scope(),
Options: vol.Options(),
- UID: vol.UID(),
- GID: vol.GID(),
+ UID: uid,
+ GID: gid,
}
utils.WriteResponse(w, http.StatusOK, volResponse)
}
@@ -130,6 +141,17 @@ func ListVolumes(w http.ResponseWriter, r *http.Request) {
}
volumeConfigs := make([]*entities.VolumeListReport, 0, len(vols))
for _, v := range vols {
+ var uid, gid int
+ uid, err = v.UID()
+ if err != nil {
+ utils.Error(w, "Error fetching volume UID", http.StatusInternalServerError, err)
+ return
+ }
+ gid, err = v.GID()
+ if err != nil {
+ utils.Error(w, "Error fetching volume GID", http.StatusInternalServerError, err)
+ return
+ }
config := entities.VolumeConfigResponse{
Name: v.Name(),
Driver: v.Driver(),
@@ -138,8 +160,8 @@ func ListVolumes(w http.ResponseWriter, r *http.Request) {
Labels: v.Labels(),
Scope: v.Scope(),
Options: v.Options(),
- UID: v.UID(),
- GID: v.GID(),
+ UID: uid,
+ GID: gid,
}
volumeConfigs = append(volumeConfigs, &entities.VolumeListReport{VolumeConfigResponse: config})
}
diff --git a/pkg/api/server/server.go b/pkg/api/server/server.go
index d68f6893a..8af6d3186 100644
--- a/pkg/api/server/server.go
+++ b/pkg/api/server/server.go
@@ -173,6 +173,10 @@ func (s *APIServer) Serve() error {
}()
}
+ // Before we start serving, ensure umask is properly set for container
+ // creation.
+ _ = syscall.Umask(0022)
+
go func() {
err := s.Server.Serve(s.Listener)
if err != nil && err != http.ErrServerClosed {
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go
index d5dce0b0f..596fc2cc1 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -741,7 +741,7 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri
if ecode, err := ctr.Wait(); err != nil {
if errors.Cause(err) == define.ErrNoSuchCtr {
// Check events
- event, err := ic.Libpod.GetLastContainerEvent(ctr.ID(), events.Exited)
+ event, err := ic.Libpod.GetLastContainerEvent(ctx, ctr.ID(), events.Exited)
if err != nil {
logrus.Errorf("Cannot get exit code: %v", err)
exitCode = define.ExecErrorCodeNotFound
@@ -871,7 +871,7 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
if ecode, err := ctr.Wait(); err != nil {
if errors.Cause(err) == define.ErrNoSuchCtr {
// Check events
- event, err := ic.Libpod.GetLastContainerEvent(ctr.ID(), events.Exited)
+ event, err := ic.Libpod.GetLastContainerEvent(ctx, ctr.ID(), events.Exited)
if err != nil {
logrus.Errorf("Cannot get exit code: %v", err)
report.ExitCode = define.ExecErrorCodeNotFound
diff --git a/pkg/domain/infra/abi/events.go b/pkg/domain/infra/abi/events.go
index 50d7727ce..7a8185445 100644
--- a/pkg/domain/infra/abi/events.go
+++ b/pkg/domain/infra/abi/events.go
@@ -9,5 +9,5 @@ import (
func (ic *ContainerEngine) Events(ctx context.Context, opts entities.EventsOptions) error {
readOpts := events.ReadOptions{FromStart: opts.FromStart, Stream: opts.Stream, Filters: opts.Filter, EventChannel: opts.EventChan, Since: opts.Since, Until: opts.Until}
- return ic.Libpod.Events(readOpts)
+ return ic.Libpod.Events(ctx, readOpts)
}
diff --git a/pkg/domain/infra/abi/pods.go b/pkg/domain/infra/abi/pods.go
index e8d55989f..d1f465362 100644
--- a/pkg/domain/infra/abi/pods.go
+++ b/pkg/domain/infra/abi/pods.go
@@ -67,14 +67,14 @@ func (ic *ContainerEngine) PodKill(ctx context.Context, namesOrIds []string, opt
for _, p := range pods {
report := entities.PodKillReport{Id: p.ID()}
conErrs, err := p.Kill(uint(sig))
- if err != nil {
+ if err != nil && errors.Cause(err) != define.ErrPodPartialFail {
report.Errs = []error{err}
reports = append(reports, &report)
continue
}
if len(conErrs) > 0 {
- for _, err := range conErrs {
- report.Errs = append(report.Errs, err)
+ for id, err := range conErrs {
+ report.Errs = append(report.Errs, errors.Wrapf(err, "error killing container %s", id))
}
reports = append(reports, &report)
continue
@@ -93,13 +93,13 @@ func (ic *ContainerEngine) PodPause(ctx context.Context, namesOrIds []string, op
for _, p := range pods {
report := entities.PodPauseReport{Id: p.ID()}
errs, err := p.Pause()
- if err != nil {
+ if err != nil && errors.Cause(err) != define.ErrPodPartialFail {
report.Errs = []error{err}
continue
}
if len(errs) > 0 {
- for _, v := range errs {
- report.Errs = append(report.Errs, v)
+ for id, v := range errs {
+ report.Errs = append(report.Errs, errors.Wrapf(v, "error pausing container %s", id))
}
reports = append(reports, &report)
continue
@@ -118,13 +118,13 @@ func (ic *ContainerEngine) PodUnpause(ctx context.Context, namesOrIds []string,
for _, p := range pods {
report := entities.PodUnpauseReport{Id: p.ID()}
errs, err := p.Unpause()
- if err != nil {
+ if err != nil && errors.Cause(err) != define.ErrPodPartialFail {
report.Errs = []error{err}
continue
}
if len(errs) > 0 {
- for _, v := range errs {
- report.Errs = append(report.Errs, v)
+ for id, v := range errs {
+ report.Errs = append(report.Errs, errors.Wrapf(v, "error unpausing container %s", id))
}
reports = append(reports, &report)
continue
@@ -143,13 +143,13 @@ func (ic *ContainerEngine) PodStop(ctx context.Context, namesOrIds []string, opt
for _, p := range pods {
report := entities.PodStopReport{Id: p.ID()}
errs, err := p.StopWithTimeout(ctx, false, options.Timeout)
- if err != nil {
+ if err != nil && errors.Cause(err) != define.ErrPodPartialFail {
report.Errs = []error{err}
continue
}
if len(errs) > 0 {
- for _, v := range errs {
- report.Errs = append(report.Errs, v)
+ for id, v := range errs {
+ report.Errs = append(report.Errs, errors.Wrapf(v, "error stopping container %s", id))
}
reports = append(reports, &report)
continue
@@ -168,14 +168,14 @@ func (ic *ContainerEngine) PodRestart(ctx context.Context, namesOrIds []string,
for _, p := range pods {
report := entities.PodRestartReport{Id: p.ID()}
errs, err := p.Restart(ctx)
- if err != nil {
+ if err != nil && errors.Cause(err) != define.ErrPodPartialFail {
report.Errs = []error{err}
reports = append(reports, &report)
continue
}
if len(errs) > 0 {
- for _, v := range errs {
- report.Errs = append(report.Errs, v)
+ for id, v := range errs {
+ report.Errs = append(report.Errs, errors.Wrapf(v, "error restarting container %s", id))
}
reports = append(reports, &report)
continue
@@ -195,14 +195,14 @@ func (ic *ContainerEngine) PodStart(ctx context.Context, namesOrIds []string, op
for _, p := range pods {
report := entities.PodStartReport{Id: p.ID()}
errs, err := p.Start(ctx)
- if err != nil {
+ if err != nil && errors.Cause(err) != define.ErrPodPartialFail {
report.Errs = []error{err}
reports = append(reports, &report)
continue
}
if len(errs) > 0 {
- for _, v := range errs {
- report.Errs = append(report.Errs, v)
+ for id, v := range errs {
+ report.Errs = append(report.Errs, errors.Wrapf(v, "error starting container %s", id))
}
reports = append(reports, &report)
continue
diff --git a/pkg/domain/infra/abi/volumes.go b/pkg/domain/infra/abi/volumes.go
index 861617eb6..8db89899e 100644
--- a/pkg/domain/infra/abi/volumes.go
+++ b/pkg/domain/infra/abi/volumes.go
@@ -95,6 +95,15 @@ func (ic *ContainerEngine) VolumeInspect(ctx context.Context, namesOrIds []strin
}
reports := make([]*entities.VolumeInspectReport, 0, len(vols))
for _, v := range vols {
+ var uid, gid int
+ uid, err = v.UID()
+ if err != nil {
+ return nil, err
+ }
+ gid, err = v.GID()
+ if err != nil {
+ return nil, err
+ }
config := entities.VolumeConfigResponse{
Name: v.Name(),
Driver: v.Driver(),
@@ -103,8 +112,8 @@ func (ic *ContainerEngine) VolumeInspect(ctx context.Context, namesOrIds []strin
Labels: v.Labels(),
Scope: v.Scope(),
Options: v.Options(),
- UID: v.UID(),
- GID: v.GID(),
+ UID: uid,
+ GID: gid,
}
reports = append(reports, &entities.VolumeInspectReport{VolumeConfigResponse: &config})
}
@@ -141,6 +150,15 @@ func (ic *ContainerEngine) VolumeList(ctx context.Context, opts entities.VolumeL
}
reports := make([]*entities.VolumeListReport, 0, len(vols))
for _, v := range vols {
+ var uid, gid int
+ uid, err = v.UID()
+ if err != nil {
+ return nil, err
+ }
+ gid, err = v.GID()
+ if err != nil {
+ return nil, err
+ }
config := entities.VolumeConfigResponse{
Name: v.Name(),
Driver: v.Driver(),
@@ -149,8 +167,8 @@ func (ic *ContainerEngine) VolumeList(ctx context.Context, opts entities.VolumeL
Labels: v.Labels(),
Scope: v.Scope(),
Options: v.Options(),
- UID: v.UID(),
- GID: v.GID(),
+ UID: uid,
+ GID: gid,
}
reports = append(reports, &entities.VolumeListReport{VolumeConfigResponse: config})
}
diff --git a/pkg/spec/createconfig.go b/pkg/spec/createconfig.go
index b1d6be016..879c66895 100644
--- a/pkg/spec/createconfig.go
+++ b/pkg/spec/createconfig.go
@@ -287,10 +287,11 @@ func (c *CreateConfig) getContainerCreateOptions(runtime *libpod.Runtime, pod *l
options = append(options, libpod.WithCommand(c.UserCommand))
}
- // Add entrypoint unconditionally
- // If it's empty it's because it was explicitly set to "" or the image
- // does not have one
- options = append(options, libpod.WithEntrypoint(c.Entrypoint))
+ // Add entrypoint if it was set
+ // If it's empty it's because it was explicitly set to ""
+ if c.Entrypoint != nil {
+ options = append(options, libpod.WithEntrypoint(c.Entrypoint))
+ }
// TODO: MNT, USER, CGROUP
options = append(options, libpod.WithStopSignal(c.StopSignal))
diff --git a/pkg/specgen/generate/oci.go b/pkg/specgen/generate/oci.go
index 3732d5431..0a485e7cd 100644
--- a/pkg/specgen/generate/oci.go
+++ b/pkg/specgen/generate/oci.go
@@ -52,10 +52,14 @@ func addRlimits(s *specgen.SpecGenerator, g *generate.Generator) error {
if err := unix.Getrlimit(unix.RLIMIT_NOFILE, &rlimit); err != nil {
logrus.Warnf("failed to return RLIMIT_NOFILE ulimit %q", err)
}
- current = rlimit.Cur
- max = rlimit.Max
+ if rlimit.Cur < current {
+ current = rlimit.Cur
+ }
+ if rlimit.Max < max {
+ max = rlimit.Max
+ }
}
- g.AddProcessRlimits("RLIMIT_NOFILE", current, max)
+ g.AddProcessRlimits("RLIMIT_NOFILE", max, current)
}
if !nprocSet {
max := kernelMax
@@ -65,10 +69,14 @@ func addRlimits(s *specgen.SpecGenerator, g *generate.Generator) error {
if err := unix.Getrlimit(unix.RLIMIT_NPROC, &rlimit); err != nil {
logrus.Warnf("failed to return RLIMIT_NPROC ulimit %q", err)
}
- current = rlimit.Cur
- max = rlimit.Max
+ if rlimit.Cur < current {
+ current = rlimit.Cur
+ }
+ if rlimit.Max < max {
+ max = rlimit.Max
+ }
}
- g.AddProcessRlimits("RLIMIT_NPROC", current, max)
+ g.AddProcessRlimits("RLIMIT_NPROC", max, current)
}
return nil
diff --git a/pkg/specgen/generate/ports.go b/pkg/specgen/generate/ports.go
index b529fd4cd..9412ecfbf 100644
--- a/pkg/specgen/generate/ports.go
+++ b/pkg/specgen/generate/ports.go
@@ -43,6 +43,8 @@ func parsePortMapping(portMappings []specgen.PortMapping) ([]ocicni.PortMapping,
containerPortValidate[proto] = make(map[string]map[uint16]uint16)
}
+ postAssignHostPort := false
+
// Iterate through all port mappings, generating OCICNI PortMapping
// structs and validating there is no overlap.
for _, port := range portMappings {
@@ -71,9 +73,6 @@ func parsePortMapping(portMappings []specgen.PortMapping) ([]ocicni.PortMapping,
return nil, nil, nil, errors.Errorf("container port number must be non-0")
}
hostPort := port.HostPort
- if hostPort == 0 {
- hostPort = containerPort
- }
if uint32(len-1)+uint32(containerPort) > 65535 {
return nil, nil, nil, errors.Errorf("container port range exceeds maximum allowable port number")
}
@@ -105,26 +104,42 @@ func parsePortMapping(portMappings []specgen.PortMapping) ([]ocicni.PortMapping,
cPort := containerPort + index
hPort := hostPort + index
- if cPort == 0 || hPort == 0 {
- return nil, nil, nil, errors.Errorf("host and container ports cannot be 0")
- }
-
- testCPort := ctrPortMap[cPort]
- if testCPort != 0 && testCPort != hPort {
- // This is an attempt to redefine a port
- return nil, nil, nil, errors.Errorf("conflicting port mappings for container port %d (protocol %s)", cPort, p)
+ if cPort == 0 {
+ return nil, nil, nil, errors.Errorf("container port cannot be 0")
}
- ctrPortMap[cPort] = hPort
- testHPort := hostPortMap[hPort]
- if testHPort != 0 && testHPort != cPort {
- return nil, nil, nil, errors.Errorf("conflicting port mappings for host port %d (protocol %s)", hPort, p)
- }
- hostPortMap[hPort] = cPort
-
- // If we have an exact duplicate, just continue
- if testCPort == hPort && testHPort == cPort {
- continue
+ // Host port is allowed to be 0. If it is, we
+ // select a random port on the host.
+ // This will happen *after* all other ports are
+ // placed, to ensure we don't accidentally
+ // select a port that a later mapping wanted.
+ if hPort == 0 {
+ // If we already have a host port
+ // assigned to their container port -
+ // just use that.
+ if ctrPortMap[cPort] != 0 {
+ hPort = ctrPortMap[cPort]
+ } else {
+ postAssignHostPort = true
+ }
+ } else {
+ testCPort := ctrPortMap[cPort]
+ if testCPort != 0 && testCPort != hPort {
+ // This is an attempt to redefine a port
+ return nil, nil, nil, errors.Errorf("conflicting port mappings for container port %d (protocol %s)", cPort, p)
+ }
+ ctrPortMap[cPort] = hPort
+
+ testHPort := hostPortMap[hPort]
+ if testHPort != 0 && testHPort != cPort {
+ return nil, nil, nil, errors.Errorf("conflicting port mappings for host port %d (protocol %s)", hPort, p)
+ }
+ hostPortMap[hPort] = cPort
+
+ // If we have an exact duplicate, just continue
+ if testCPort == hPort && testHPort == cPort {
+ continue
+ }
}
// We appear to be clear. Make an OCICNI port
@@ -142,6 +157,61 @@ func parsePortMapping(portMappings []specgen.PortMapping) ([]ocicni.PortMapping,
}
}
+ // Handle any 0 host ports now by setting random container ports.
+ if postAssignHostPort {
+ remadeMappings := make([]ocicni.PortMapping, 0, len(finalMappings))
+
+ // Iterate over all
+ for _, p := range finalMappings {
+ if p.HostPort != 0 {
+ remadeMappings = append(remadeMappings, p)
+ continue
+ }
+
+ hostIPMap := hostPortValidate[p.Protocol]
+ ctrIPMap := containerPortValidate[p.Protocol]
+
+ hostPortMap, ok := hostIPMap[p.HostIP]
+ if !ok {
+ hostPortMap = make(map[uint16]uint16)
+ hostIPMap[p.HostIP] = hostPortMap
+ }
+ ctrPortMap, ok := ctrIPMap[p.HostIP]
+ if !ok {
+ ctrPortMap = make(map[uint16]uint16)
+ ctrIPMap[p.HostIP] = ctrPortMap
+ }
+
+ // See if container port has been used elsewhere
+ if ctrPortMap[uint16(p.ContainerPort)] != 0 {
+ // Duplicate definition. Let's not bother
+ // including it.
+ continue
+ }
+
+ // Max retries to ensure we don't loop forever.
+ for i := 0; i < 15; i++ {
+ candidate, err := getRandomPort()
+ if err != nil {
+ return nil, nil, nil, errors.Wrapf(err, "error getting candidate host port for container port %d", p.ContainerPort)
+ }
+
+ if hostPortMap[uint16(candidate)] == 0 {
+ logrus.Debugf("Successfully assigned container port %d to host port %d (IP %s Protocol %s)", p.ContainerPort, candidate, p.HostIP, p.Protocol)
+ hostPortMap[uint16(candidate)] = uint16(p.ContainerPort)
+ ctrPortMap[uint16(p.ContainerPort)] = uint16(candidate)
+ p.HostPort = int32(candidate)
+ break
+ }
+ }
+ if p.HostPort == 0 {
+ return nil, nil, nil, errors.Errorf("could not find open host port to map container port %d to", p.ContainerPort)
+ }
+ remadeMappings = append(remadeMappings, p)
+ }
+ return remadeMappings, containerPortValidate, hostPortValidate, nil
+ }
+
return finalMappings, containerPortValidate, hostPortValidate, nil
}
diff --git a/pkg/specgen/specgen.go b/pkg/specgen/specgen.go
index 03e840ab4..327c15c5a 100644
--- a/pkg/specgen/specgen.go
+++ b/pkg/specgen/specgen.go
@@ -430,7 +430,8 @@ type PortMapping struct {
ContainerPort uint16 `json:"container_port"`
// HostPort is the port number that will be forwarded from the host into
// the container.
- // If omitted, will be assumed to be identical to
+ // If omitted, a random port on the host (guaranteed to be over 1024)
+ // will be assigned.
HostPort uint16 `json:"host_port,omitempty"`
// Range is the number of ports that will be forwarded, starting at
// HostPort and ContainerPort and counting up.
diff --git a/pkg/systemd/generate/common.go b/pkg/systemd/generate/common.go
index fe56dc874..d6d18a810 100644
--- a/pkg/systemd/generate/common.go
+++ b/pkg/systemd/generate/common.go
@@ -1,6 +1,8 @@
package generate
import (
+ "strings"
+
"github.com/pkg/errors"
)
@@ -44,6 +46,9 @@ func filterPodFlags(command []string) []string {
i++
continue
}
+ if strings.HasPrefix(s, "--pod=") || strings.HasPrefix(s, "--pod-id-file=") {
+ continue
+ }
processed = append(processed, s)
}
return processed
diff --git a/pkg/systemd/generate/common_test.go b/pkg/systemd/generate/common_test.go
index f53bb7828..389c30f59 100644
--- a/pkg/systemd/generate/common_test.go
+++ b/pkg/systemd/generate/common_test.go
@@ -1,6 +1,7 @@
package generate
import (
+ "strings"
"testing"
"github.com/stretchr/testify/assert"
@@ -14,12 +15,16 @@ func TestFilterPodFlags(t *testing.T) {
{[]string{"podman", "pod", "create"}},
{[]string{"podman", "pod", "create", "--name", "foo"}},
{[]string{"podman", "pod", "create", "--pod-id-file", "foo"}},
+ {[]string{"podman", "pod", "create", "--pod-id-file=foo"}},
{[]string{"podman", "run", "--pod", "foo"}},
+ {[]string{"podman", "run", "--pod=foo"}},
}
for _, test := range tests {
processed := filterPodFlags(test.input)
- assert.NotContains(t, processed, "--pod-id-file")
- assert.NotContains(t, processed, "--pod")
+ for _, s := range processed {
+ assert.False(t, strings.HasPrefix(s, "--pod-id-file"))
+ assert.False(t, strings.HasPrefix(s, "--pod"))
+ }
}
}
diff --git a/pkg/terminal/console_unix.go b/pkg/terminal/console_unix.go
new file mode 100644
index 000000000..6eee6aa2f
--- /dev/null
+++ b/pkg/terminal/console_unix.go
@@ -0,0 +1,8 @@
+// +build !windows
+
+package terminal
+
+// SetConsole for non-windows environments is a no-op
+func SetConsole() error {
+ return nil
+}
diff --git a/pkg/terminal/console_windows.go b/pkg/terminal/console_windows.go
new file mode 100644
index 000000000..c7691857c
--- /dev/null
+++ b/pkg/terminal/console_windows.go
@@ -0,0 +1,37 @@
+// +build windows
+
+package terminal
+
+import (
+ "github.com/sirupsen/logrus"
+ "golang.org/x/sys/windows"
+)
+
+// SetConsole switches the windows terminal mode to be able to handle colors, etc
+func SetConsole() error {
+ if err := setConsoleMode(windows.Stdout, windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING); err != nil {
+ return err
+ }
+ if err := setConsoleMode(windows.Stderr, windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING); err != nil {
+ return err
+ }
+ if err := setConsoleMode(windows.Stdin, windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING); err != nil {
+ return err
+ }
+ return nil
+}
+
+func setConsoleMode(handle windows.Handle, flags uint32) error {
+ var mode uint32
+ err := windows.GetConsoleMode(handle, &mode)
+ if err != nil {
+ return err
+ }
+ if err := windows.SetConsoleMode(handle, mode|flags); err != nil {
+ // In similar code, it is not considered an error if we cannot set the
+ // console mode. Following same line of thinking here.
+ logrus.WithError(err).Error("Failed to set console mode for cli")
+ }
+
+ return nil
+}
diff --git a/pkg/varlinkapi/attach.go b/pkg/varlinkapi/attach.go
index 731d89b8f..8acf2a1b6 100644
--- a/pkg/varlinkapi/attach.go
+++ b/pkg/varlinkapi/attach.go
@@ -4,6 +4,7 @@ package varlinkapi
import (
"bufio"
+ "context"
"io"
"github.com/containers/libpod/v2/libpod"
@@ -89,7 +90,7 @@ func (i *VarlinkAPI) Attach(call iopodman.VarlinkCall, name string, detachKeys s
if ecode, err := ctr.Wait(); err != nil {
if errors.Cause(err) == define.ErrNoSuchCtr {
// Check events
- event, err := i.Runtime.GetLastContainerEvent(ctr.ID(), events.Exited)
+ event, err := i.Runtime.GetLastContainerEvent(context.Background(), ctr.ID(), events.Exited)
if err != nil {
logrus.Errorf("Cannot get exit code: %v", err)
exitCode = define.ExecErrorCodeNotFound
diff --git a/pkg/varlinkapi/events.go b/pkg/varlinkapi/events.go
index 2e468b706..910b64a57 100644
--- a/pkg/varlinkapi/events.go
+++ b/pkg/varlinkapi/events.go
@@ -3,6 +3,7 @@
package varlinkapi
import (
+ "context"
"time"
"github.com/containers/libpod/v2/libpod/events"
@@ -27,7 +28,7 @@ func (i *VarlinkAPI) GetEvents(call iopodman.VarlinkCall, filter []string, since
eventChannel := make(chan *events.Event)
go func() {
readOpts := events.ReadOptions{FromStart: fromStart, Stream: stream, Filters: filter, EventChannel: eventChannel}
- eventsError = i.Runtime.Events(readOpts)
+ eventsError = i.Runtime.Events(context.Background(), readOpts)
}()
if eventsError != nil {
return call.ReplyErrorOccurred(eventsError.Error())