aboutsummaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/api/handlers/compat/containers.go13
-rw-r--r--pkg/api/handlers/compat/images.go1
-rw-r--r--pkg/api/handlers/compat/networks.go22
-rw-r--r--pkg/api/handlers/libpod/images.go70
-rw-r--r--pkg/api/handlers/libpod/networks.go16
-rw-r--r--pkg/api/handlers/libpod/pods.go2
-rw-r--r--pkg/api/server/register_images.go34
-rw-r--r--pkg/api/server/register_networks.go12
-rw-r--r--pkg/bindings/images/images.go28
-rw-r--r--pkg/bindings/network/network.go8
-rw-r--r--pkg/domain/entities/containers.go1
-rw-r--r--pkg/domain/entities/images.go17
-rw-r--r--pkg/domain/infra/abi/containers.go9
-rw-r--r--pkg/domain/infra/abi/containers_runlabel.go5
-rw-r--r--pkg/domain/infra/abi/images.go14
-rw-r--r--pkg/domain/infra/tunnel/images.go23
-rw-r--r--pkg/domain/infra/tunnel/network.go2
-rw-r--r--pkg/ps/ps.go85
-rw-r--r--pkg/specgen/generate/oci.go3
-rw-r--r--pkg/systemd/generate/containers.go3
20 files changed, 331 insertions, 37 deletions
diff --git a/pkg/api/handlers/compat/containers.go b/pkg/api/handlers/compat/containers.go
index 1ae6a990b..b1ef08cda 100644
--- a/pkg/api/handlers/compat/containers.go
+++ b/pkg/api/handlers/compat/containers.go
@@ -5,6 +5,7 @@ import (
"fmt"
"net/http"
"strings"
+ "syscall"
"github.com/containers/podman/v2/libpod"
"github.com/containers/podman/v2/libpod/define"
@@ -169,16 +170,16 @@ func KillContainer(w http.ResponseWriter, r *http.Request) {
return
}
- err = con.Kill(uint(sig))
+ signal := uint(sig)
+
+ err = con.Kill(signal)
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrapf(err, "unable to kill Container %s", name))
}
- if utils.IsLibpodRequest(r) {
- // the kill behavior for docker differs from podman in that they appear to wait
- // for the Container to croak so the exit code is accurate immediately after the
- // kill is sent. libpod does not. but we can add a wait here only for the docker
- // side of things and mimic that behavior
+ // Docker waits for the container to stop if the signal is 0 or
+ // SIGKILL.
+ if !utils.IsLibpodRequest(r) && (signal == 0 || syscall.Signal(signal) == syscall.SIGKILL) {
if _, err = con.Wait(); err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrapf(err, "failed to wait for Container %s", con.ID()))
return
diff --git a/pkg/api/handlers/compat/images.go b/pkg/api/handlers/compat/images.go
index 6872dd780..8765e20ca 100644
--- a/pkg/api/handlers/compat/images.go
+++ b/pkg/api/handlers/compat/images.go
@@ -365,7 +365,6 @@ func LoadImages(w http.ResponseWriter, r *http.Request) {
return
}
id, err := runtime.LoadImage(r.Context(), "", f.Name(), writer, "")
- //id, err := runtime.Import(r.Context())
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to load image"))
return
diff --git a/pkg/api/handlers/compat/networks.go b/pkg/api/handlers/compat/networks.go
index 80b7505df..87b947549 100644
--- a/pkg/api/handlers/compat/networks.go
+++ b/pkg/api/handlers/compat/networks.go
@@ -5,6 +5,7 @@ import (
"net"
"net/http"
"os"
+ "strings"
"syscall"
"time"
@@ -177,9 +178,11 @@ func ListNetworks(w http.ResponseWriter, r *http.Request) {
utils.InternalServerError(w, err)
return
}
+
+ filterNames, nameFilterExists := query.Filters["name"]
// TODO remove when filters are implemented
- if len(query.Filters) > 0 {
- utils.InternalServerError(w, errors.New("filters for listing networks is not implemented"))
+ if (!nameFilterExists && len(query.Filters) > 0) || len(query.Filters) > 1 {
+ utils.InternalServerError(w, errors.New("only the name filter for listing networks is implemented"))
return
}
netNames, err := network.GetNetworkNamesFromFileSystem(config)
@@ -187,6 +190,21 @@ func ListNetworks(w http.ResponseWriter, r *http.Request) {
utils.InternalServerError(w, err)
return
}
+
+ // filter by name
+ if nameFilterExists {
+ names := []string{}
+ for _, name := range netNames {
+ for _, filter := range filterNames {
+ if strings.Contains(name, filter) {
+ names = append(names, name)
+ break
+ }
+ }
+ }
+ netNames = names
+ }
+
reports := make([]*types.NetworkResource, 0, len(netNames))
for _, name := range netNames {
report, err := getNetworkResourceByName(name, runtime)
diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go
index 8d3fc4e00..85f7903dc 100644
--- a/pkg/api/handlers/libpod/images.go
+++ b/pkg/api/handlers/libpod/images.go
@@ -234,6 +234,76 @@ func ExportImage(w http.ResponseWriter, r *http.Request) {
utils.WriteResponse(w, http.StatusOK, rdr)
}
+func ExportImages(w http.ResponseWriter, r *http.Request) {
+ var (
+ output string
+ )
+ runtime := r.Context().Value("runtime").(*libpod.Runtime)
+ decoder := r.Context().Value("decoder").(*schema.Decoder)
+ query := struct {
+ Compress bool `schema:"compress"`
+ Format string `schema:"format"`
+ References []string `schema:"references"`
+ }{
+ Format: define.OCIArchive,
+ }
+
+ 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
+ }
+
+ // References are mandatory!
+ if len(query.References) == 0 {
+ utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
+ errors.New("No references"))
+ return
+ }
+
+ // Format is mandatory! Currently, we only support multi-image docker
+ // archives.
+ switch query.Format {
+ case define.V2s2Archive:
+ tmpfile, err := ioutil.TempFile("", "api.tar")
+ if err != nil {
+ utils.Error(w, "unable to create tmpfile", http.StatusInternalServerError, errors.Wrap(err, "unable to create tempfile"))
+ return
+ }
+ output = tmpfile.Name()
+ if err := tmpfile.Close(); err != nil {
+ utils.Error(w, "unable to close tmpfile", http.StatusInternalServerError, errors.Wrap(err, "unable to close tempfile"))
+ return
+ }
+ default:
+ utils.Error(w, "unsupported format", http.StatusInternalServerError, errors.Errorf("unsupported format %q", query.Format))
+ return
+ }
+ defer os.RemoveAll(output)
+
+ // Use the ABI image engine to share as much code as possible.
+ opts := entities.ImageSaveOptions{
+ Compress: query.Compress,
+ Format: query.Format,
+ MultiImageArchive: true,
+ Output: output,
+ }
+
+ imageEngine := abi.ImageEngine{Libpod: runtime}
+ if err := imageEngine.Save(r.Context(), query.References[0], query.References[1:], opts); err != nil {
+ utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, err)
+ return
+ }
+
+ rdr, err := os.Open(output)
+ if err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to read the exported tarfile"))
+ return
+ }
+ defer rdr.Close()
+ utils.WriteResponse(w, http.StatusOK, rdr)
+}
+
func ImagesLoad(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
decoder := r.Context().Value("decoder").(*schema.Decoder)
diff --git a/pkg/api/handlers/libpod/networks.go b/pkg/api/handlers/libpod/networks.go
index 475522664..dfece2a4e 100644
--- a/pkg/api/handlers/libpod/networks.go
+++ b/pkg/api/handlers/libpod/networks.go
@@ -42,7 +42,21 @@ func CreateNetwork(w http.ResponseWriter, r *http.Request) {
}
func ListNetworks(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
- options := entities.NetworkListOptions{}
+ decoder := r.Context().Value("decoder").(*schema.Decoder)
+ query := struct {
+ Filter string `schema:"filter"`
+ }{
+ // override any golang type defaults
+ }
+ 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
+ }
+
+ options := entities.NetworkListOptions{
+ Filter: query.Filter,
+ }
ic := abi.ContainerEngine{Libpod: runtime}
reports, err := ic.NetworkList(r.Context(), options)
if err != nil {
diff --git a/pkg/api/handlers/libpod/pods.go b/pkg/api/handlers/libpod/pods.go
index 8f8292567..82a7299b2 100644
--- a/pkg/api/handlers/libpod/pods.go
+++ b/pkg/api/handlers/libpod/pods.go
@@ -327,7 +327,7 @@ func PodTop(w http.ResponseWriter, r *http.Request) {
name := utils.GetName(r)
pod, err := runtime.LookupPod(name)
if err != nil {
- utils.ContainerNotFound(w, name, err)
+ utils.PodNotFound(w, name, err)
return
}
diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go
index 64258a073..b1007fe09 100644
--- a/pkg/api/server/register_images.go
+++ b/pkg/api/server/register_images.go
@@ -1028,6 +1028,40 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// 500:
// $ref: '#/responses/InternalError'
r.Handle(VersionedPath("/libpod/images/{name:.*}/get"), s.APIHandler(libpod.ExportImage)).Methods(http.MethodGet)
+ // swagger:operation GET /libpod/images/export libpod libpodExportImages
+ // ---
+ // tags:
+ // - images
+ // summary: Export multiple images
+ // description: Export multiple images into a single object. Only `docker-archive` is currently supported.
+ // parameters:
+ // - in: query
+ // name: format
+ // type: string
+ // description: format for exported image (only docker-archive is supported)
+ // - in: query
+ // name: references
+ // description: references to images to export
+ // type: array
+ // items:
+ // type: string
+ // - in: query
+ // name: compress
+ // type: boolean
+ // description: use compression on image
+ // produces:
+ // - application/json
+ // responses:
+ // 200:
+ // description: no error
+ // schema:
+ // type: string
+ // format: binary
+ // 404:
+ // $ref: '#/responses/NoSuchImage'
+ // 500:
+ // $ref: '#/responses/InternalError'
+ r.Handle(VersionedPath("/libpod/images/export"), s.APIHandler(libpod.ExportImages)).Methods(http.MethodGet)
// swagger:operation GET /libpod/images/{name:.*}/json libpod libpodInspectImage
// ---
// tags:
diff --git a/pkg/api/server/register_networks.go b/pkg/api/server/register_networks.go
index 7918ad4a2..61916eedf 100644
--- a/pkg/api/server/register_networks.go
+++ b/pkg/api/server/register_networks.go
@@ -61,6 +61,11 @@ func (s *APIServer) registerNetworkHandlers(r *mux.Router) error {
// - networks (compat)
// summary: List networks
// description: Display summary of network configurations
+ // parameters:
+ // - in: query
+ // name: filters
+ // type: string
+ // description: JSON encoded value of the filters (a map[string][]string) to process on the networks list. Only the name filter is supported.
// produces:
// - application/json
// responses:
@@ -106,7 +111,7 @@ func (s *APIServer) registerNetworkHandlers(r *mux.Router) error {
// required: true
// description: the name of the network
// - in: query
- // name: Force
+ // name: force
// type: boolean
// description: remove containers associated with network
// produces:
@@ -152,6 +157,11 @@ func (s *APIServer) registerNetworkHandlers(r *mux.Router) error {
// - networks
// summary: List networks
// description: Display summary of network configurations
+ // parameters:
+ // - in: query
+ // name: filter
+ // type: string
+ // description: Provide filter values (e.g. 'name=podman')
// produces:
// - application/json
// responses:
diff --git a/pkg/bindings/images/images.go b/pkg/bindings/images/images.go
index 9f6e78b79..a80c94025 100644
--- a/pkg/bindings/images/images.go
+++ b/pkg/bindings/images/images.go
@@ -128,6 +128,34 @@ func Load(ctx context.Context, r io.Reader, name *string) (*entities.ImageLoadRe
return &report, response.Process(&report)
}
+func MultiExport(ctx context.Context, namesOrIds []string, w io.Writer, format *string, compress *bool) error {
+ conn, err := bindings.GetClient(ctx)
+ if err != nil {
+ return err
+ }
+ params := url.Values{}
+ if format != nil {
+ params.Set("format", *format)
+ }
+ if compress != nil {
+ params.Set("compress", strconv.FormatBool(*compress))
+ }
+ for _, ref := range namesOrIds {
+ params.Add("references", ref)
+ }
+ response, err := conn.DoRequest(nil, http.MethodGet, "/images/export", params, nil)
+ if err != nil {
+ return err
+ }
+
+ if response.StatusCode/100 == 2 || response.StatusCode/100 == 3 {
+ _, err = io.Copy(w, response.Body)
+ return err
+ }
+ return response.Process(nil)
+
+}
+
// Export saves an image from local storage as a tarball or image archive. The optional format
// parameter is used to change the format of the output.
func Export(ctx context.Context, nameOrID string, w io.Writer, format *string, compress *bool) error {
diff --git a/pkg/bindings/network/network.go b/pkg/bindings/network/network.go
index fd1111282..d8dc7e352 100644
--- a/pkg/bindings/network/network.go
+++ b/pkg/bindings/network/network.go
@@ -70,7 +70,7 @@ func Remove(ctx context.Context, nameOrID string, force *bool) ([]*entities.Netw
}
// List returns a summary of all CNI network configurations
-func List(ctx context.Context) ([]*entities.NetworkListReport, error) {
+func List(ctx context.Context, options entities.NetworkListOptions) ([]*entities.NetworkListReport, error) {
var (
netList []*entities.NetworkListReport
)
@@ -78,7 +78,11 @@ func List(ctx context.Context) ([]*entities.NetworkListReport, error) {
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/networks/json", nil, nil)
+ params := url.Values{}
+ if options.Filter != "" {
+ params.Set("filter", options.Filter)
+ }
+ response, err := conn.DoRequest(nil, http.MethodGet, "/networks/json", params, nil)
if err != nil {
return netList, err
}
diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go
index c8894300b..16997cdd1 100644
--- a/pkg/domain/entities/containers.go
+++ b/pkg/domain/entities/containers.go
@@ -282,6 +282,7 @@ type ContainerListOptions struct {
Quiet bool
Size bool
Sort string
+ Storage bool
Sync bool
Watch uint
}
diff --git a/pkg/domain/entities/images.go b/pkg/domain/entities/images.go
index 3a12a4e22..2a8133680 100644
--- a/pkg/domain/entities/images.go
+++ b/pkg/domain/entities/images.go
@@ -271,11 +271,22 @@ type ImageImportReport struct {
Id string //nolint
}
+// ImageSaveOptions provide options for saving images.
type ImageSaveOptions struct {
+ // Compress layers when saving to a directory.
Compress bool
- Format string
- Output string
- Quiet bool
+ // Format of saving the image: oci-archive, oci-dir (directory with oci
+ // manifest type), docker-archive, docker-dir (directory with v2s2
+ // manifest type).
+ Format string
+ // MultiImageArchive denotes if the created archive shall include more
+ // than one image. Additional tags will be interpreted as references
+ // to images which are added to the archive.
+ MultiImageArchive bool
+ // Output - write image to the specified path.
+ Output string
+ // Quiet - suppress output when copying images
+ Quiet bool
}
// ImageTreeOptions provides options for ImageEngine.Tree()
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go
index 3fee5d394..21618f555 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -174,6 +174,12 @@ func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []strin
return err
}
}
+ if c.AutoRemove() {
+ // Issue #7384: if the container is configured for
+ // auto-removal, it might already have been removed at
+ // this point.
+ return nil
+ }
return c.Cleanup(ctx)
})
if err != nil {
@@ -792,6 +798,9 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri
}
func (ic *ContainerEngine) ContainerList(ctx context.Context, options entities.ContainerListOptions) ([]entities.ListContainer, error) {
+ if options.Latest {
+ options.Last = 1
+ }
return ps.GetContainerLists(ic.Libpod, options)
}
diff --git a/pkg/domain/infra/abi/containers_runlabel.go b/pkg/domain/infra/abi/containers_runlabel.go
index ab2316d47..3983ba3a8 100644
--- a/pkg/domain/infra/abi/containers_runlabel.go
+++ b/pkg/domain/infra/abi/containers_runlabel.go
@@ -36,6 +36,11 @@ func (ic *ContainerEngine) ContainerRunlabel(ctx context.Context, label string,
return err
}
+ if options.Display {
+ fmt.Printf("command: %s\n", strings.Join(append([]string{os.Args[0]}, cmd[1:]...), " "))
+ return nil
+ }
+
stdErr := os.Stderr
stdOut := os.Stdout
stdIn := os.Stdin
diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go
index 6b94ca9c0..33060b34b 100644
--- a/pkg/domain/infra/abi/images.go
+++ b/pkg/domain/infra/abi/images.go
@@ -14,7 +14,6 @@ import (
"github.com/containers/common/pkg/config"
"github.com/containers/image/v5/docker"
- dockerarchive "github.com/containers/image/v5/docker/archive"
"github.com/containers/image/v5/docker/reference"
"github.com/containers/image/v5/manifest"
"github.com/containers/image/v5/signature"
@@ -230,15 +229,6 @@ func (ir *ImageEngine) Pull(ctx context.Context, rawImage string, options entiti
}
}
- // Special-case for docker-archive which allows multiple tags.
- if imageRef.Transport().Name() == dockerarchive.Transport.Name() {
- newImage, err := ir.Libpod.ImageRuntime().LoadFromArchiveReference(ctx, imageRef, options.SignaturePolicy, writer)
- if err != nil {
- return nil, err
- }
- return &entities.ImagePullReport{Images: []string{newImage[0].ID()}}, nil
- }
-
var registryCreds *types.DockerAuthConfig
if len(options.Username) > 0 && len(options.Password) > 0 {
registryCreds = &types.DockerAuthConfig{
@@ -481,6 +471,10 @@ func (ir *ImageEngine) Import(ctx context.Context, opts entities.ImageImportOpti
}
func (ir *ImageEngine) Save(ctx context.Context, nameOrID string, tags []string, options entities.ImageSaveOptions) error {
+ if options.MultiImageArchive {
+ nameOrIDs := append([]string{nameOrID}, tags...)
+ return ir.Libpod.ImageRuntime().SaveImages(ctx, nameOrIDs, options.Format, options.Output, options.Quiet)
+ }
newImage, err := ir.Libpod.ImageRuntime().NewFromLocal(nameOrID)
if err != nil {
return err
diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go
index b255c5da4..185cc2f9a 100644
--- a/pkg/domain/infra/tunnel/images.go
+++ b/pkg/domain/infra/tunnel/images.go
@@ -251,12 +251,23 @@ func (ir *ImageEngine) Save(ctx context.Context, nameOrID string, tags []string,
return err
}
- exErr := images.Export(ir.ClientCxt, nameOrID, f, &options.Format, &options.Compress)
- if err := f.Close(); err != nil {
- return err
- }
- if exErr != nil {
- return exErr
+ if options.MultiImageArchive {
+ exErr := images.MultiExport(ir.ClientCxt, append([]string{nameOrID}, tags...), f, &options.Format, &options.Compress)
+ if err := f.Close(); err != nil {
+ return err
+ }
+ if exErr != nil {
+ return exErr
+ }
+ } else {
+ // FIXME: tags are entirely ignored here but shouldn't.
+ exErr := images.Export(ir.ClientCxt, nameOrID, f, &options.Format, &options.Compress)
+ if err := f.Close(); err != nil {
+ return err
+ }
+ if exErr != nil {
+ return exErr
+ }
}
if options.Format != "oci-dir" && options.Format != "docker-dir" {
diff --git a/pkg/domain/infra/tunnel/network.go b/pkg/domain/infra/tunnel/network.go
index 2b197cac0..074425087 100644
--- a/pkg/domain/infra/tunnel/network.go
+++ b/pkg/domain/infra/tunnel/network.go
@@ -8,7 +8,7 @@ import (
)
func (ic *ContainerEngine) NetworkList(ctx context.Context, options entities.NetworkListOptions) ([]*entities.NetworkListReport, error) {
- return network.List(ic.ClientCxt)
+ return network.List(ic.ClientCxt, options)
}
func (ic *ContainerEngine) NetworkInspect(ctx context.Context, namesOrIds []string, options entities.NetworkInspectOptions) ([]entities.NetworkInspectReport, error) {
diff --git a/pkg/ps/ps.go b/pkg/ps/ps.go
index 4c5f60844..8087507e2 100644
--- a/pkg/ps/ps.go
+++ b/pkg/ps/ps.go
@@ -14,6 +14,7 @@ import (
lpfilters "github.com/containers/podman/v2/libpod/filters"
"github.com/containers/podman/v2/pkg/domain/entities"
psdefine "github.com/containers/podman/v2/pkg/ps/define"
+ "github.com/containers/storage"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
@@ -54,12 +55,12 @@ func GetContainerLists(runtime *libpod.Runtime, options entities.ContainerListOp
return nil, err
}
if options.Last > 0 {
- // Sort the containers we got
+ // Sort the libpod containers
sort.Sort(SortCreateTime{SortContainers: cons})
// we should perform the lopping before we start getting
// the expensive information on containers
if options.Last < len(cons) {
- cons = cons[len(cons)-options.Last:]
+ cons = cons[:options.Last]
}
}
for _, con := range cons {
@@ -68,7 +69,31 @@ func GetContainerLists(runtime *libpod.Runtime, options entities.ContainerListOp
return nil, err
}
pss = append(pss, listCon)
+ }
+
+ if options.All && options.Storage {
+ externCons, err := runtime.StorageContainers()
+ if err != nil {
+ return nil, err
+ }
+
+ for _, con := range externCons {
+ listCon, err := ListStorageContainer(runtime, con, options)
+ if err != nil {
+ return nil, err
+ }
+ pss = append(pss, listCon)
+ }
+ }
+
+ // Sort the containers we got
+ sort.Sort(SortPSCreateTime{SortPSContainers: pss})
+ if options.Last > 0 {
+ // only return the "last" containers caller requested
+ if options.Last < len(pss) {
+ pss = pss[:options.Last]
+ }
}
return pss, nil
}
@@ -199,6 +224,48 @@ func ListContainerBatch(rt *libpod.Runtime, ctr *libpod.Container, opts entities
return ps, nil
}
+func ListStorageContainer(rt *libpod.Runtime, ctr storage.Container, opts entities.ContainerListOptions) (entities.ListContainer, error) {
+ name := "unknown"
+ if len(ctr.Names) > 0 {
+ name = ctr.Names[0]
+ }
+
+ ps := entities.ListContainer{
+ ID: ctr.ID,
+ Created: ctr.Created.Unix(),
+ ImageID: ctr.ImageID,
+ State: "storage",
+ Names: []string{name},
+ }
+
+ buildahCtr, err := rt.IsBuildahContainer(ctr.ID)
+ if err != nil {
+ return ps, errors.Wrapf(err, "error determining buildah container for container %s", ctr.ID)
+ }
+
+ if buildahCtr {
+ ps.Command = []string{"buildah"}
+ } else {
+ ps.Command = []string{"storage"}
+ }
+
+ imageName := ""
+ if ctr.ImageID != "" {
+ names, err := rt.ImageRuntime().ImageNames(ctr.ImageID)
+ if err != nil {
+ return ps, err
+ }
+ if len(names) > 0 {
+ imageName = names[0]
+ }
+ } else if buildahCtr {
+ imageName = "scratch"
+ }
+
+ ps.Image = imageName
+ return ps, nil
+}
+
func getNamespaceInfo(path string) (string, error) {
val, err := os.Readlink(path)
if err != nil {
@@ -223,5 +290,17 @@ func (a SortContainers) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
type SortCreateTime struct{ SortContainers }
func (a SortCreateTime) Less(i, j int) bool {
- return a.SortContainers[i].CreatedTime().Before(a.SortContainers[j].CreatedTime())
+ return a.SortContainers[i].CreatedTime().After(a.SortContainers[j].CreatedTime())
+}
+
+// SortPSContainers helps us set-up ability to sort by createTime
+type SortPSContainers []entities.ListContainer
+
+func (a SortPSContainers) Len() int { return len(a) }
+func (a SortPSContainers) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+
+type SortPSCreateTime struct{ SortPSContainers }
+
+func (a SortPSCreateTime) Less(i, j int) bool {
+ return a.SortPSContainers[i].Created > a.SortPSContainers[j].Created
}
diff --git a/pkg/specgen/generate/oci.go b/pkg/specgen/generate/oci.go
index fd324c6e1..b57ddf1aa 100644
--- a/pkg/specgen/generate/oci.go
+++ b/pkg/specgen/generate/oci.go
@@ -353,6 +353,9 @@ func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runt
configSpec.Annotations[define.InspectAnnotationInit] = define.InspectResponseFalse
}
+ if s.OOMScoreAdj != nil {
+ g.SetProcessOOMScoreAdj(*s.OOMScoreAdj)
+ }
setProcOpts(s, &g)
return configSpec, nil
diff --git a/pkg/systemd/generate/containers.go b/pkg/systemd/generate/containers.go
index caf5de357..a4fdae46e 100644
--- a/pkg/systemd/generate/containers.go
+++ b/pkg/systemd/generate/containers.go
@@ -220,6 +220,9 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst
case "--replace":
hasReplaceParam = true
}
+ if strings.HasPrefix(p, "--name=") {
+ hasNameParam = true
+ }
}
if !hasDetachParam {