Skip to content

Commit

Permalink
Merge pull request #5863 from vrothberg/v2-fix-rmi
Browse files Browse the repository at this point in the history
podman rmi: refactor logic
  • Loading branch information
openshift-merge-robot authored Apr 21, 2020
2 parents 89276a5 + 09dc701 commit 90636fe
Show file tree
Hide file tree
Showing 34 changed files with 423 additions and 259 deletions.
1 change: 1 addition & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ linters:
- misspell
- prealloc
- unparam
- nakedret
linters-settings:
errcheck:
check-blank: false
Expand Down
2 changes: 1 addition & 1 deletion cmd/podman/containers/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ func run(cmd *cobra.Command, args []string) error {
return nil
}
if runRmi {
_, err := registry.ImageEngine().Delete(registry.GetContext(), []string{args[0]}, entities.ImageDeleteOptions{})
_, err := registry.ImageEngine().Remove(registry.GetContext(), []string{args[0]}, entities.ImageRemoveOptions{})
if err != nil {
logrus.Errorf("%s", errors.Wrapf(err, "failed removing image"))
}
Expand Down
32 changes: 12 additions & 20 deletions cmd/podman/images/rm.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package images

import (
"fmt"
"os"

"github.com/containers/libpod/cmd/podman/registry"
"github.com/containers/libpod/pkg/domain/entities"
Expand All @@ -23,7 +22,7 @@ var (
podman image rm c4dfb1609ee2 93fd78260bd1 c0ed59d05ff7`,
}

imageOpts = entities.ImageDeleteOptions{}
imageOpts = entities.ImageRemoveOptions{}
)

func init() {
Expand All @@ -40,32 +39,25 @@ func imageRemoveFlagSet(flags *pflag.FlagSet) {
flags.BoolVarP(&imageOpts.All, "all", "a", false, "Remove all images")
flags.BoolVarP(&imageOpts.Force, "force", "f", false, "Force Removal of the image")
}
func rm(cmd *cobra.Command, args []string) error {

func rm(cmd *cobra.Command, args []string) error {
if len(args) < 1 && !imageOpts.All {
return errors.Errorf("image name or ID must be specified")
}
if len(args) > 0 && imageOpts.All {
return errors.Errorf("when using the --all switch, you may not pass any images names or IDs")
}
report, err := registry.ImageEngine().Delete(registry.GetContext(), args, imageOpts)
if err != nil {
switch {
case report != nil && report.ImageNotFound != nil:
fmt.Fprintln(os.Stderr, err.Error())
registry.SetExitCode(2)
case report != nil && report.ImageInUse != nil:
fmt.Fprintln(os.Stderr, err.Error())
default:
return err

report, err := registry.ImageEngine().Remove(registry.GetContext(), args, imageOpts)
if report != nil {
for _, u := range report.Untagged {
fmt.Println("Untagged: " + u)
}
for _, d := range report.Deleted {
fmt.Println("Deleted: " + d)
}
registry.SetExitCode(report.ExitCode)
}

for _, u := range report.Untagged {
fmt.Println("Untagged: " + u)
}
for _, d := range report.Deleted {
fmt.Println("Deleted: " + d)
}
return nil
return err
}
3 changes: 2 additions & 1 deletion cmd/podman/system/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ func service(cmd *cobra.Command, args []string) error {

logrus.Warn("This function is EXPERIMENTAL")
fmt.Fprintf(os.Stderr, "This function is EXPERIMENTAL.\n")
return registry.ContainerEngine().RestService(registry.GetContext(), opts)

return restService(opts, cmd.Flags(), registry.PodmanConfig())
}

func resolveApiURI(_url []string) (string, error) {
Expand Down
57 changes: 57 additions & 0 deletions cmd/podman/system/service_abi.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// +build ABISupport

package system

import (
"context"
"net"
"strings"

api "github.com/containers/libpod/pkg/api/server"
"github.com/containers/libpod/pkg/domain/entities"
"github.com/containers/libpod/pkg/domain/infra"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/pflag"
)

func restService(opts entities.ServiceOptions, flags *pflag.FlagSet, cfg *entities.PodmanConfig) error {
var (
listener *net.Listener
err error
)

if opts.URI != "" {
fields := strings.Split(opts.URI, ":")
if len(fields) == 1 {
return errors.Errorf("%s is an invalid socket destination", opts.URI)
}
address := strings.Join(fields[1:], ":")
l, err := net.Listen(fields[0], address)
if err != nil {
return errors.Wrapf(err, "unable to create socket %s", opts.URI)
}
listener = &l
}

rt, err := infra.GetRuntime(context.Background(), flags, cfg)
if err != nil {
return err
}

server, err := api.NewServerWithSettings(rt, opts.Timeout, listener)
if err != nil {
return err
}
defer func() {
if err := server.Shutdown(); err != nil {
logrus.Warnf("Error when stopping API service: %s", err)
}
}()

err = server.Serve()
if listener != nil {
_ = (*listener).Close()
}
return err
}
14 changes: 14 additions & 0 deletions cmd/podman/system/service_unsupported.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// +build !ABISupport

package system

import (
"errors"

"github.com/containers/libpod/pkg/domain/entities"
"github.com/spf13/pflag"
)

func restService(opts entities.ServiceOptions, flags *pflag.FlagSet, cfg *entities.PodmanConfig) error {
return errors.New("not supported")
}
15 changes: 12 additions & 3 deletions hack/golangci-lint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,22 @@
# Need to run linter twice to cover all the build tags code paths

declare -A BUILD_TAGS
# TODO: add systemd tag
BUILD_TAGS[default]="apparmor,seccomp,selinux"
BUILD_TAGS[abi]="${BUILD_TAGS[default]},ABISupport,varlink,!remoteclient"
BUILD_TAGS[tunnel]="${BUILD_TAGS[default]},!ABISupport,!varlink,remoteclient"
BUILD_TAGS[tunnel]="${BUILD_TAGS[default]},!ABISupport,varlink,remoteclient"

declare -A SKIP_DIRS
SKIP_DIRS[abi]=""
# TODO: add "ABISupport" build tag to pkg/api
SKIP_DIRS[tunnel]="pkg/api"

[[ $1 == run ]] && shift

for i in tunnel abi; do
echo Build Tags: ${BUILD_TAGS[$i]}
golangci-lint run --build-tags=${BUILD_TAGS[$i]} "$@"
echo ""
echo Running golangci-lint for "$i"
echo Build Tags "$i": ${BUILD_TAGS[$i]}
echo Skipped directories "$i": ${SKIP_DIRS[$i]}
golangci-lint run --build-tags=${BUILD_TAGS[$i]} --skip-dirs=${SKIP_DIRS[$i]} "$@"
done
4 changes: 2 additions & 2 deletions pkg/api/handlers/compat/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (

"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/events"
"github.com/containers/libpod/pkg/api/handlers"
"github.com/containers/libpod/pkg/api/handlers/utils"
"github.com/containers/libpod/pkg/domain/entities"
"github.com/gorilla/schema"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
Expand Down Expand Up @@ -70,7 +70,7 @@ func GetEvents(w http.ResponseWriter, r *http.Request) {
coder.SetEscapeHTML(true)

for event := range eventChannel {
e := handlers.EventToApiEvent(event)
e := entities.ConvertToEntitiesEvent(*event)
if err := coder.Encode(e); err != nil {
logrus.Errorf("unable to write json: %q", err)
}
Expand Down
28 changes: 28 additions & 0 deletions pkg/api/handlers/libpod/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/containers/libpod/pkg/api/handlers"
"github.com/containers/libpod/pkg/api/handlers/utils"
"github.com/containers/libpod/pkg/domain/entities"
"github.com/containers/libpod/pkg/domain/infra/abi"
"github.com/containers/libpod/pkg/util"
utils2 "github.com/containers/libpod/utils"
"github.com/gorilla/schema"
Expand Down Expand Up @@ -698,3 +699,30 @@ func SearchImages(w http.ResponseWriter, r *http.Request) {

utils.WriteResponse(w, http.StatusOK, reports)
}

// ImagesRemove is the endpoint for image removal.
func ImagesRemove(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
decoder := r.Context().Value("decoder").(*schema.Decoder)
query := struct {
All bool `schema:"all"`
Force bool `schema:"force"`
Images []string `schema:"images"`
}{
All: false,
Force: false,
}

if err := decoder.Decode(&query, r.URL.Query()); err != nil {
utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
return
}

opts := entities.ImageRemoveOptions{All: query.All, Force: query.Force}

imageEngine := abi.ImageEngine{Libpod: runtime}
rmReport, rmError := imageEngine.Remove(r.Context(), query.Images, opts)
report := handlers.LibpodImagesRemoveReport{ImageRemoveReport: *rmReport, Error: rmError.Error()}
utils.WriteResponse(w, http.StatusOK, report)
}
7 changes: 7 additions & 0 deletions pkg/api/handlers/swagger/swagger.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ type swagLibpodImagesPullResponse struct {
Body handlers.LibpodImagesPullReport
}

// Remove response
// swagger:response DocsLibpodImagesRemoveResponse
type swagLibpodImagesRemoveResponse struct {
// in:body
Body handlers.LibpodImagesRemoveReport
}

// Delete response
// swagger:response DocsImageDeleteResponse
type swagImageDeleteResponse struct {
Expand Down
58 changes: 8 additions & 50 deletions pkg/api/handlers/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,13 @@ import (
"context"
"encoding/json"
"fmt"
"strconv"
"time"

"github.com/containers/image/v5/manifest"
"github.com/containers/libpod/libpod/events"
libpodImage "github.com/containers/libpod/libpod/image"
"github.com/containers/libpod/pkg/domain/entities"
docker "github.com/docker/docker/api/types"
dockerContainer "github.com/docker/docker/api/types/container"
dockerEvents "github.com/docker/docker/api/types/events"
dockerNetwork "github.com/docker/docker/api/types/network"
"github.com/docker/go-connections/nat"
"github.com/pkg/errors"
Expand All @@ -39,6 +36,14 @@ type LibpodImagesPullReport struct {
ID string `json:"id"`
}

// LibpodImagesRemoveReport is the return type for image removal via the rest
// api.
type LibpodImagesRemoveReport struct {
entities.ImageRemoveReport
// Image removal requires is to return data and an error.
Error string
}

type ContainersPruneReport struct {
docker.ContainersPruneReport
}
Expand Down Expand Up @@ -143,10 +148,6 @@ type PodCreateConfig struct {
Share string `json:"share"`
}

type Event struct {
dockerEvents.Message
}

type HistoryResponse struct {
ID string `json:"Id"`
Created int64 `json:"Created"`
Expand All @@ -173,49 +174,6 @@ type ExecCreateResponse struct {
docker.IDResponse
}

func (e *Event) ToLibpodEvent() *events.Event {
exitCode, err := strconv.Atoi(e.Actor.Attributes["containerExitCode"])
if err != nil {
return nil
}
status, err := events.StringToStatus(e.Action)
if err != nil {
return nil
}
t, err := events.StringToType(e.Type)
if err != nil {
return nil
}
lp := events.Event{
ContainerExitCode: exitCode,
ID: e.Actor.ID,
Image: e.Actor.Attributes["image"],
Name: e.Actor.Attributes["name"],
Status: status,
Time: time.Unix(e.Time, e.TimeNano),
Type: t,
}
return &lp
}

func EventToApiEvent(e *events.Event) *Event {
return &Event{dockerEvents.Message{
Type: e.Type.String(),
Action: e.Status.String(),
Actor: dockerEvents.Actor{
ID: e.ID,
Attributes: map[string]string{
"image": e.Image,
"name": e.Name,
"containerExitCode": strconv.Itoa(e.ContainerExitCode),
},
},
Scope: "local",
Time: e.Time.Unix(),
TimeNano: e.Time.UnixNano(),
}}
}

func ImageToImageSummary(l *libpodImage.Image) (*entities.ImageSummary, error) {
containers, err := l.Containers()
if err != nil {
Expand Down
32 changes: 32 additions & 0 deletions pkg/api/server/register_images.go
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,38 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// 500:
// $ref: '#/responses/InternalError'
r.Handle(VersionedPath("/libpod/images/import"), s.APIHandler(libpod.ImagesImport)).Methods(http.MethodPost)
// swagger:operation GET /libpod/images/remove libpod libpodImagesRemove
// ---
// tags:
// - images
// summary: Remove one or more images from the storage.
// description: Remove one or more images from the storage.
// parameters:
// - in: query
// name: images
// description: Images IDs or names to remove.
// type: array
// items:
// type: string
// - in: query
// name: all
// description: Remove all images.
// type: boolean
// default: true
// - in: query
// name: force
// description: Force image removal (including containers using the images).
// type: boolean
// produces:
// - application/json
// responses:
// 200:
// $ref: "#/responses/DocsLibpodImagesRemoveResponse"
// 400:
// $ref: "#/responses/BadParamError"
// 500:
// $ref: '#/responses/InternalError'
r.Handle(VersionedPath("/libpod/images/remove"), s.APIHandler(libpod.ImagesRemove)).Methods(http.MethodGet)
// swagger:operation POST /libpod/images/pull libpod libpodImagesPull
// ---
// tags:
Expand Down
Loading

0 comments on commit 90636fe

Please sign in to comment.