-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Fix handling of container remove #9014
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,7 +14,9 @@ import ( | |
"github.com/containers/podman/v2/libpod/define" | ||
"github.com/containers/podman/v2/pkg/api/handlers" | ||
"github.com/containers/podman/v2/pkg/api/handlers/utils" | ||
"github.com/containers/podman/v2/pkg/domain/entities" | ||
"github.com/containers/podman/v2/pkg/domain/filters" | ||
"github.com/containers/podman/v2/pkg/domain/infra/abi" | ||
"github.com/containers/podman/v2/pkg/ps" | ||
"github.com/containers/podman/v2/pkg/signal" | ||
"github.com/docker/docker/api/types" | ||
|
@@ -29,9 +31,11 @@ import ( | |
func RemoveContainer(w http.ResponseWriter, r *http.Request) { | ||
decoder := r.Context().Value("decoder").(*schema.Decoder) | ||
query := struct { | ||
Force bool `schema:"force"` | ||
Vols bool `schema:"v"` | ||
Link bool `schema:"link"` | ||
All bool `schema:"all"` | ||
Force bool `schema:"force"` | ||
Ignore bool `schema:"ignore"` | ||
Link bool `schema:"link"` | ||
Volumes bool `schema:"v"` | ||
}{ | ||
// override any golang type defaults | ||
} | ||
|
@@ -49,34 +53,31 @@ func RemoveContainer(w http.ResponseWriter, r *http.Request) { | |
} | ||
|
||
runtime := r.Context().Value("runtime").(*libpod.Runtime) | ||
// Now use the ABI implementation to prevent us from having duplicate | ||
// code. | ||
containerEngine := abi.ContainerEngine{Libpod: runtime} | ||
name := utils.GetName(r) | ||
con, err := runtime.LookupContainer(name) | ||
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 { | ||
options := entities.RmOptions{ | ||
All: query.All, | ||
Force: query.Force, | ||
Volumes: query.Volumes, | ||
Ignore: query.Ignore, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit, alpha order this plz. |
||
} | ||
report, err := containerEngine.ContainerRm(r.Context(), []string{name}, options) | ||
if err != nil { | ||
if errors.Cause(err) == define.ErrNoSuchCtr { | ||
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) | ||
utils.InternalServerError(w, err) | ||
return | ||
} | ||
|
||
if err := runtime.RemoveContainer(r.Context(), con, query.Force, query.Vols); err != nil { | ||
utils.InternalServerError(w, err) | ||
if report[0].Err != nil { | ||
utils.InternalServerError(w, report[0].Err) | ||
return | ||
} | ||
|
||
utils.WriteResponse(w, http.StatusNoContent, nil) | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -122,6 +122,8 @@ type PruneOptions struct { | |
//go:generate go run ../generator/generator.go RemoveOptions | ||
// RemoveOptions are optional options for removing containers | ||
type RemoveOptions struct { | ||
All *bool | ||
Ignore *bool | ||
Force *bool | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm going to assume that Tom will ask you to sort those |
||
Volumes *bool | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -264,30 +264,30 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string, | |
reports := []*entities.RmReport{} | ||
|
||
names := namesOrIds | ||
for _, cidFile := range options.CIDFiles { | ||
content, err := ioutil.ReadFile(cidFile) | ||
if err != nil { | ||
return nil, errors.Wrap(err, "error reading CIDFile") | ||
} | ||
id := strings.Split(string(content), "\n")[0] | ||
names = append(names, id) | ||
} | ||
|
||
// Attempt to remove named containers directly from storage, if container is defined in libpod | ||
// this will fail and code will fall through to removing the container from libpod.` | ||
tmpNames := []string{} | ||
for _, ctr := range names { | ||
report := entities.RmReport{Id: ctr} | ||
if err := ic.Libpod.RemoveStorageContainer(ctr, options.Force); err != nil { | ||
report.Err = ic.Libpod.RemoveStorageContainer(ctr, options.Force) | ||
switch errors.Cause(report.Err) { | ||
case nil: | ||
// remove container names that we successfully deleted | ||
tmpNames = append(tmpNames, ctr) | ||
} else { | ||
reports = append(reports, &report) | ||
case define.ErrNoSuchCtr: | ||
// There is still a potential this is a libpod container | ||
tmpNames = append(tmpNames, ctr) | ||
mheon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
default: | ||
if _, err := ic.Libpod.LookupContainer(ctr); errors.Cause(err) == define.ErrNoSuchCtr { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This bit seems unnecessary - I don't see any way we fail in a fashion that's not ErrNoSuchCtr before There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The use case we are trying to fix #8735, is the case where we created a buildah container that is in use, and fails. This would end up in this block, and now we check to see if it is a libpod container. Since it is not, we return the error. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure you're right here - the check for whether a container is a Libpod container in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you run @edsantiago test you will see this happen. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Then we need to catch this inside There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. RemoveStorageContainer is not broken, it is returning a valid error, that we are returning to the user. The problem is we are ignoring the error and then falling through to the libpod remove, which finds that there is no Container libpod container, and reports container does not exists. |
||
// remove container failed, but not a libpod container | ||
reports = append(reports, &report) | ||
continue | ||
} | ||
// attempt to remove as a libpod container | ||
tmpNames = append(tmpNames, ctr) | ||
} | ||
} | ||
if len(tmpNames) < len(names) { | ||
names = tmpNames | ||
} | ||
names = tmpNames | ||
|
||
ctrs, err := getContainersByContext(options.All, options.Latest, names, ic.Libpod) | ||
if err != nil && !(options.Ignore && errors.Cause(err) == define.ErrNoSuchCtr) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the compat endpoint. We shouldn't be modifying its parameters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the only endpoint we have for removing containers. All of the Docker parameters still work, is it invalid to use additional libpod params on a compat endpoint?
@baude @jwhonce WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can make it conditional which is something other endpoints are doing.
utils.IsLibpodRequest(r)
returns a boolean that indicates if the request was made against alibpod/...
endpoint.