Skip to content

Commit

Permalink
Merge pull request containers#7785 from mheon/backports_211
Browse files Browse the repository at this point in the history
Backports for v2.1.1
  • Loading branch information
openshift-merge-robot authored Sep 25, 2020
2 parents 17db985 + 65f2f1a commit bb8e77d
Show file tree
Hide file tree
Showing 74 changed files with 422 additions and 221 deletions.
20 changes: 20 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
# Release Notes

## 2.1.1
### Changes
- The `podman info` command now includes the cgroup manager Podman is using.

### Bugfixes
- Fixed a bug where Podman would not build with the `varlink` build tag enabled.
- Fixed a bug where the `podman save` command could, when asked to save multiple images, write its progress bar to the archive instead of the terminal, producing a corrupted archive.
- Fixed a bug where the `json-file` log driver did not write logs.
- Fixed a bug where `podman-remote start --attach` did not properly handle detaching using the detach keys.
- Fixed a bug where `podman pod ps --filter label=...` did not work.
- Fixed a bug where the `podman build` command did not respect the `--runtime` flag.

### API
- The REST API now includes a Server header in all responses.
- Fixed a bug where the Libpod and Compat Attach endpoints could terminate early, before sending all output from the container.
- Fixed a bug where the Compat Create endpoint for containers did not properly handle the Interactive parameter.
- Fixed a bug where the Compat Kill endpoint for containers could continue to run after a fatal error.
- Fixed a bug where the Limit parameter of the Compat List endpoint for Containers did not properly handle a limit of 0 (returning nothing, instead of all containers) ([#7722](https://github.com/containers/podman/issues/7722)).
- The Libpod Stats endpoint for containers is being deprecated and will be replaced by a similar endpoint with additional features in a future release.

## 2.1.0
### Features
- A new command, `podman image mount`, has been added. This allows for an image to be mounted, read-only, to inspect its contents without creating a container from it ([#1433](https://github.com/containers/podman/issues/1433)).
Expand Down
1 change: 1 addition & 0 deletions cmd/podman/images/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,7 @@ func buildFlagsWrapperToOptions(c *cobra.Command, contextDir string, flags *buil
Quiet: flags.Quiet,
RemoveIntermediateCtrs: flags.Rm,
ReportWriter: reporter,
Runtime: containerConfig.RuntimePath,
RuntimeArgs: runtimeFlags,
SignBy: flags.SignBy,
SignaturePolicyPath: flags.SignaturePolicy,
Expand Down
7 changes: 1 addition & 6 deletions cmd/podman/images/save.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ func save(cmd *cobra.Command, args []string) (finalErr error) {
return errors.Errorf("--compress can only be set when --format is either 'oci-dir' or 'docker-dir'")
}
if len(saveOpts.Output) == 0 {
saveOpts.Quiet = true
fi := os.Stdout
if terminal.IsTerminal(int(fi.Fd())) {
return errors.Errorf("refusing to save to terminal. Use -o flag or redirect")
Expand Down Expand Up @@ -122,12 +123,6 @@ func save(cmd *cobra.Command, args []string) (finalErr error) {
tags = args[1:]
}

// Decide whether c/image's progress bars should use stderr or stdout.
// If the output is set of stdout, any log message there would corrupt
// the tarfile.
if saveOpts.Output == os.Stdout.Name() {
saveOpts.Quiet = true
}
err := registry.ImageEngine().Save(context.Background(), args[0], tags, saveOpts)
if err == nil {
succeeded = true
Expand Down
2 changes: 1 addition & 1 deletion cmd/podman/pods/ps.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func pods(cmd *cobra.Command, _ []string) error {
if cmd.Flag("filter").Changed {
psInput.Filters = make(map[string][]string)
for _, f := range inputFilters {
split := strings.Split(f, "=")
split := strings.SplitN(f, "=", 2)
if len(split) < 2 {
return errors.Errorf("filter input must be in the form of filter=value: %s is invalid", f)
}
Expand Down
4 changes: 3 additions & 1 deletion docs/source/markdown/podman-load.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ podman\-load - Load an image from a container image archive into container stora
**podman image load** [*options*] [*name*[:*tag*]]

## DESCRIPTION
**podman load** loads an image from either an **oci-archive** or **docker-archive** stored on the local machine into container storage. **podman load** reads from stdin by default or a file if the **input** option is set.
**podman load** loads an image from either an **oci-archive** or a **docker-archive** stored on the local machine into container storage. **podman load** reads from stdin by default or a file if the **input** option is set.
You can also specify a name for the image if the archive does not contain a named reference, of if you want an additional name for the local image.

The local client further supports loading an **oci-dir** or a **docker-dir** as created with **podman save** (1).

The **quiet** option suppresses the progress output when set.
Note: `:` is a restricted character and cannot be part of the file name.

Expand Down
1 change: 1 addition & 0 deletions libpod/define/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type Info struct {
type HostInfo struct {
Arch string `json:"arch"`
BuildahVersion string `json:"buildahVersion"`
CgroupManager string `json:"cgroupManager"`
CGroupsVersion string `json:"cgroupVersion"`
Conmon *ConmonInfo `json:"conmon"`
CPUs int `json:"cpus"`
Expand Down
1 change: 1 addition & 0 deletions libpod/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ func (r *Runtime) hostInfo() (*define.HostInfo, error) {
info := define.HostInfo{
Arch: runtime.GOARCH,
BuildahVersion: buildah.Version,
CgroupManager: r.config.Engine.CgroupManager,
Linkmode: linkmode.Linkmode(),
CPUs: runtime.NumCPU(),
Distribution: hostDistributionInfo,
Expand Down
27 changes: 16 additions & 11 deletions libpod/oci_conmon_exec_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -537,9 +537,6 @@ func attachExecHTTP(c *Container, sessionID string, r *http.Request, w http.Resp
}
}()

// Make a channel to pass errors back
errChan := make(chan error)

attachStdout := true
attachStderr := true
attachStdin := true
Expand Down Expand Up @@ -580,13 +577,16 @@ func attachExecHTTP(c *Container, sessionID string, r *http.Request, w http.Resp
hijackWriteErrorAndClose(deferredErr, c.ID(), isTerminal, httpCon, httpBuf)
}()

stdoutChan := make(chan error)
stdinChan := make(chan error)

// Next, STDIN. Avoid entirely if attachStdin unset.
if attachStdin {
go func() {
logrus.Debugf("Beginning STDIN copy")
_, err := utils.CopyDetachable(conn, httpBuf, detachKeys)
logrus.Debugf("STDIN copy completed")
errChan <- err
stdinChan <- err
}()
}

Expand All @@ -613,19 +613,24 @@ func attachExecHTTP(c *Container, sessionID string, r *http.Request, w http.Resp
logrus.Debugf("Performing non-terminal HTTP attach for container %s", c.ID())
err = httpAttachNonTerminalCopy(conn, httpBuf, c.ID(), attachStdin, attachStdout, attachStderr)
}
errChan <- err
stdoutChan <- err
logrus.Debugf("STDOUT/ERR copy completed")
}()

if cancel != nil {
for {
select {
case err := <-errChan:
return err
case err := <-stdoutChan:
if err != nil {
return err
}

return nil
case err := <-stdinChan:
if err != nil {
return err
}
case <-cancel:
return nil
}
} else {
var connErr error = <-errChan
return connErr
}
}
31 changes: 18 additions & 13 deletions libpod/oci_conmon_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -555,9 +555,6 @@ func (r *ConmonOCIRuntime) HTTPAttach(ctr *Container, req *http.Request, w http.
return err
}

// Make a channel to pass errors back
errChan := make(chan error)

attachStdout := true
attachStderr := true
attachStdin := true
Expand Down Expand Up @@ -672,6 +669,9 @@ func (r *ConmonOCIRuntime) HTTPAttach(ctr *Container, req *http.Request, w http.

logrus.Debugf("Forwarding attach output for container %s", ctr.ID())

stdoutChan := make(chan error)
stdinChan := make(chan error)

// Handle STDOUT/STDERR
go func() {
var err error
Expand All @@ -690,28 +690,33 @@ func (r *ConmonOCIRuntime) HTTPAttach(ctr *Container, req *http.Request, w http.
logrus.Debugf("Performing non-terminal HTTP attach for container %s", ctr.ID())
err = httpAttachNonTerminalCopy(conn, httpBuf, ctr.ID(), attachStdin, attachStdout, attachStderr)
}
errChan <- err
stdoutChan <- err
logrus.Debugf("STDOUT/ERR copy completed")
}()
// Next, STDIN. Avoid entirely if attachStdin unset.
if attachStdin {
go func() {
_, err := utils.CopyDetachable(conn, httpBuf, detach)
logrus.Debugf("STDIN copy completed")
errChan <- err
stdinChan <- err
}()
}

if cancel != nil {
for {
select {
case err := <-errChan:
return err
case err := <-stdoutChan:
if err != nil {
return err
}

return nil
case err := <-stdinChan:
if err != nil {
return err
}
case <-cancel:
return nil
}
} else {
var connErr error = <-errChan
return connErr
}
}

Expand Down Expand Up @@ -1330,10 +1335,10 @@ func (r *ConmonOCIRuntime) sharedConmonArgs(ctr *Container, cuuid, bundlePath, p
switch logDriver {
case define.JournaldLogging:
logDriverArg = define.JournaldLogging
case define.JSONLogging:
fallthrough
case define.NoLogging:
logDriverArg = define.NoLogging
case define.JSONLogging:
fallthrough
default: //nolint-stylecheck
// No case here should happen except JSONLogging, but keep this here in case the options are extended
logrus.Errorf("%s logging specified but not supported. Choosing k8s-file logging instead", ctr.LogDriver())
Expand Down
25 changes: 22 additions & 3 deletions pkg/api/handlers/compat/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/docker/go-connections/nat"
"github.com/gorilla/schema"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)

func RemoveContainer(w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -44,8 +45,25 @@ func RemoveContainer(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
name := utils.GetName(r)
con, err := runtime.LookupContainer(name)
if err != nil {
utils.ContainerNotFound(w, name, err)
if err != nil && errors.Cause(err) == define.ErrNoSuchCtr {
// Failed to get container. If force is specified, get the container's ID
// and evict it
if !query.Force {
utils.ContainerNotFound(w, name, err)
return
}

if _, err := runtime.EvictContainer(r.Context(), name, query.Vols); err != nil {
if errors.Cause(err) == define.ErrNoSuchCtr {
logrus.Debugf("Ignoring error (--allow-missing): %q", err)
w.WriteHeader(http.StatusNoContent)
return
}
logrus.Warn(errors.Wrapf(err, "Failed to evict container: %q", name))
utils.InternalServerError(w, err)
return
}
w.WriteHeader(http.StatusNoContent)
return
}

Expand Down Expand Up @@ -85,7 +103,7 @@ func ListContainers(w http.ResponseWriter, r *http.Request) {
utils.InternalServerError(w, err)
return
}
if _, found := r.URL.Query()["limit"]; found && query.Limit != -1 {
if _, found := r.URL.Query()["limit"]; found && query.Limit > 0 {
last := query.Limit
if len(containers) > last {
containers = containers[len(containers)-last:]
Expand Down Expand Up @@ -175,6 +193,7 @@ func KillContainer(w http.ResponseWriter, r *http.Request) {
err = con.Kill(signal)
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrapf(err, "unable to kill Container %s", name))
return
}

// Docker waits for the container to stop if the signal is 0 or
Expand Down
2 changes: 1 addition & 1 deletion pkg/api/handlers/compat/containers_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ func makeCreateConfig(ctx context.Context, containerConfig *config.Config, input
ImageID: newImage.ID(),
BuiltinImgVolumes: nil, // podman
ImageVolumeType: "", // podman
Interactive: false,
Interactive: input.OpenStdin,
// IpcMode: input.HostConfig.IpcMode,
Labels: input.Labels,
LogDriver: input.HostConfig.LogConfig.Type, // is this correct
Expand Down
17 changes: 10 additions & 7 deletions pkg/api/server/handler_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,18 @@ func (s *APIServer) APIHandler(h http.HandlerFunc) http.HandlerFunc {
}

// TODO: Use r.ConnContext when ported to go 1.13
c := context.WithValue(r.Context(), "decoder", s.Decoder) //nolint
c = context.WithValue(c, "runtime", s.Runtime) //nolint
c = context.WithValue(c, "shutdownFunc", s.Shutdown) //nolint
c = context.WithValue(c, "idletracker", s.idleTracker) //nolint
c := context.WithValue(r.Context(), "decoder", s.Decoder) // nolint
c = context.WithValue(c, "runtime", s.Runtime) // nolint
c = context.WithValue(c, "shutdownFunc", s.Shutdown) // nolint
c = context.WithValue(c, "idletracker", s.idleTracker) // nolint
r = r.WithContext(c)

v := utils.APIVersion[utils.CompatTree][utils.CurrentAPIVersion]
w.Header().Set("API-Version", fmt.Sprintf("%d.%d", v.Major, v.Minor))
w.Header().Set("Libpod-API-Version", utils.APIVersion[utils.LibpodTree][utils.CurrentAPIVersion].String())
cv := utils.APIVersion[utils.CompatTree][utils.CurrentAPIVersion]
w.Header().Set("API-Version", fmt.Sprintf("%d.%d", cv.Major, cv.Minor))

lv := utils.APIVersion[utils.LibpodTree][utils.CurrentAPIVersion].String()
w.Header().Set("Libpod-API-Version", lv)
w.Header().Set("Server", "Libpod/"+lv+" ("+runtime.GOOS+")")

h(w, r)
}
Expand Down
62 changes: 51 additions & 11 deletions pkg/domain/infra/tunnel/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -481,27 +481,67 @@ func startAndAttach(ic *ContainerEngine, name string, detachKeys *string, input,

func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []string, options entities.ContainerStartOptions) ([]*entities.ContainerStartReport, error) {
reports := []*entities.ContainerStartReport{}
for _, name := range namesOrIds {
var exitCode = define.ExecErrorCodeGeneric
ctrs, err := getContainersByContext(ic.ClientCxt, false, false, namesOrIds)
if err != nil {
return nil, err
}
// There can only be one container if attach was used
for i, ctr := range ctrs {
name := ctr.ID
report := entities.ContainerStartReport{
Id: name,
RawInput: name,
ExitCode: 125,
RawInput: namesOrIds[i],
ExitCode: exitCode,
}
ctrRunning := ctr.State == define.ContainerStateRunning.String()
if options.Attach {
report.Err = startAndAttach(ic, name, &options.DetachKeys, options.Stdin, options.Stdout, options.Stderr)
if report.Err == nil {
exitCode, err := containers.Wait(ic.ClientCxt, name, nil)
if err == nil {
report.ExitCode = int(exitCode)
err = startAndAttach(ic, name, &options.DetachKeys, options.Stdin, options.Stdout, options.Stderr)
if err == define.ErrDetach {
// User manually detached
// Exit cleanly immediately
report.Err = err
reports = append(reports, &report)
return reports, nil
}
if ctrRunning {
reports = append(reports, &report)
return reports, nil
}

if err != nil {
report.ExitCode = define.ExitCode(report.Err)
report.Err = err
reports = append(reports, &report)
return reports, errors.Wrapf(report.Err, "unable to start container %s", name)
}
exitCode, err := containers.Wait(ic.ClientCxt, name, nil)
if err == define.ErrNoSuchCtr {
// Check events
event, err := ic.GetLastContainerEvent(ctx, name, events.Exited)
if err != nil {
logrus.Errorf("Cannot get exit code: %v", err)
report.ExitCode = define.ExecErrorCodeNotFound
} else {
report.ExitCode = event.ContainerExitCode
}
} else {
report.ExitCode = define.ExitCode(report.Err)
report.ExitCode = int(exitCode)
}
reports = append(reports, &report)
return reports, nil
}
report.Err = containers.Start(ic.ClientCxt, name, &options.DetachKeys)
report.ExitCode = define.ExitCode(report.Err)
// Start the container if it's not running already.
if !ctrRunning {
err = containers.Start(ic.ClientCxt, name, &options.DetachKeys)
if err != nil {
report.Err = errors.Wrapf(err, "unable to start container %q", name)
report.ExitCode = define.ExitCode(err)
reports = append(reports, &report)
continue
}
}
report.ExitCode = 0
reports = append(reports, &report)
}
return reports, nil
Expand Down
Loading

0 comments on commit bb8e77d

Please sign in to comment.