Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backports for v2.1.1 #7785

Merged
merged 16 commits into from
Sep 25, 2020
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
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