mirror of
https://github.com/containers/podman.git
synced 2025-07-01 08:07:03 +08:00
Merge pull request #2831 from baude/remotetree
podman-remote image tree
This commit is contained in:
18
API.md
18
API.md
@ -5,6 +5,8 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in
|
|||||||
|
|
||||||
[func BuildImage(build: BuildInfo) MoreResponse](#BuildImage)
|
[func BuildImage(build: BuildInfo) MoreResponse](#BuildImage)
|
||||||
|
|
||||||
|
[func BuildImageHierarchyMap(name: string) string](#BuildImageHierarchyMap)
|
||||||
|
|
||||||
[func Commit(name: string, image_name: string, changes: []string, author: string, message: string, pause: bool, manifestType: string) string](#Commit)
|
[func Commit(name: string, image_name: string, changes: []string, author: string, message: string, pause: bool, manifestType: string) string](#Commit)
|
||||||
|
|
||||||
[func ContainerArtifacts(name: string, artifactName: string) string](#ContainerArtifacts)
|
[func ContainerArtifacts(name: string, artifactName: string) string](#ContainerArtifacts)
|
||||||
@ -57,6 +59,8 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in
|
|||||||
|
|
||||||
[func GetInfo() PodmanInfo](#GetInfo)
|
[func GetInfo() PodmanInfo](#GetInfo)
|
||||||
|
|
||||||
|
[func GetLayersMapWithImageInfo() string](#GetLayersMapWithImageInfo)
|
||||||
|
|
||||||
[func GetPod(name: string) ListPodData](#GetPod)
|
[func GetPod(name: string) ListPodData](#GetPod)
|
||||||
|
|
||||||
[func GetPodStats(name: string) string, ContainerStats](#GetPodStats)
|
[func GetPodStats(name: string) string, ContainerStats](#GetPodStats)
|
||||||
@ -259,6 +263,11 @@ method BuildImage(build: [BuildInfo](#BuildInfo)) [MoreResponse](#MoreResponse)<
|
|||||||
BuildImage takes a [BuildInfo](#BuildInfo) structure and builds an image. At a minimum, you must provide the
|
BuildImage takes a [BuildInfo](#BuildInfo) structure and builds an image. At a minimum, you must provide the
|
||||||
'dockerfile' and 'tags' options in the BuildInfo structure. It will return a [MoreResponse](#MoreResponse) structure
|
'dockerfile' and 'tags' options in the BuildInfo structure. It will return a [MoreResponse](#MoreResponse) structure
|
||||||
that contains the build logs and resulting image ID.
|
that contains the build logs and resulting image ID.
|
||||||
|
### <a name="BuildImageHierarchyMap"></a>func BuildImageHierarchyMap
|
||||||
|
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
|
||||||
|
|
||||||
|
method BuildImageHierarchyMap(name: [string](https://godoc.org/builtin#string)) [string](https://godoc.org/builtin#string)</div>
|
||||||
|
BuildImageHierarchyMap is for the development of Podman and should not be used.
|
||||||
### <a name="Commit"></a>func Commit
|
### <a name="Commit"></a>func Commit
|
||||||
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
|
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
|
||||||
|
|
||||||
@ -396,7 +405,7 @@ $ varlink call -m unix:/run/podman/io.podman/io.podman.DeleteUnusedImages
|
|||||||
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
|
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
|
||||||
|
|
||||||
method Diff(name: [string](https://godoc.org/builtin#string)) [DiffInfo](#DiffInfo)</div>
|
method Diff(name: [string](https://godoc.org/builtin#string)) [DiffInfo](#DiffInfo)</div>
|
||||||
|
Diff returns a diff between libpod objects
|
||||||
### <a name="ExportContainer"></a>func ExportContainer
|
### <a name="ExportContainer"></a>func ExportContainer
|
||||||
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
|
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
|
||||||
|
|
||||||
@ -520,6 +529,11 @@ If the image caGetImage returns be found, [ImageNotFound](#ImageNotFound) will b
|
|||||||
method GetInfo() [PodmanInfo](#PodmanInfo)</div>
|
method GetInfo() [PodmanInfo](#PodmanInfo)</div>
|
||||||
GetInfo returns a [PodmanInfo](#PodmanInfo) struct that describes podman and its host such as storage stats,
|
GetInfo returns a [PodmanInfo](#PodmanInfo) struct that describes podman and its host such as storage stats,
|
||||||
build information of Podman, and system-wide registries.
|
build information of Podman, and system-wide registries.
|
||||||
|
### <a name="GetLayersMapWithImageInfo"></a>func GetLayersMapWithImageInfo
|
||||||
|
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
|
||||||
|
|
||||||
|
method GetLayersMapWithImageInfo() [string](https://godoc.org/builtin#string)</div>
|
||||||
|
GetLayersMapWithImageInfo is for the development of Podman and should not be used.
|
||||||
### <a name="GetPod"></a>func GetPod
|
### <a name="GetPod"></a>func GetPod
|
||||||
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
|
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
|
||||||
|
|
||||||
@ -1507,6 +1521,8 @@ containers [int](https://godoc.org/builtin#int)
|
|||||||
labels [map[string]](#map[string])
|
labels [map[string]](#map[string])
|
||||||
|
|
||||||
isParent [bool](https://godoc.org/builtin#bool)
|
isParent [bool](https://godoc.org/builtin#bool)
|
||||||
|
|
||||||
|
topLayer [string](https://godoc.org/builtin#string)
|
||||||
### <a name="ImageHistory"></a>type ImageHistory
|
### <a name="ImageHistory"></a>type ImageHistory
|
||||||
|
|
||||||
ImageHistory describes the returned structure from ImageHistory.
|
ImageHistory describes the returned structure from ImageHistory.
|
||||||
|
@ -5,9 +5,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/containers/libpod/cmd/podman/cliconfig"
|
"github.com/containers/libpod/cmd/podman/cliconfig"
|
||||||
"github.com/containers/libpod/cmd/podman/libpodruntime"
|
|
||||||
"github.com/containers/libpod/libpod/image"
|
"github.com/containers/libpod/libpod/image"
|
||||||
units "github.com/docker/go-units"
|
"github.com/containers/libpod/pkg/adapter"
|
||||||
|
"github.com/docker/go-units"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
@ -41,16 +41,6 @@ func init() {
|
|||||||
treeCommand.Flags().BoolVar(&treeCommand.WhatRequires, "whatrequires", false, "Show all child images and layers of the specified image")
|
treeCommand.Flags().BoolVar(&treeCommand.WhatRequires, "whatrequires", false, "Show all child images and layers of the specified image")
|
||||||
}
|
}
|
||||||
|
|
||||||
// infoImage keep information of Image along with all associated layers
|
|
||||||
type infoImage struct {
|
|
||||||
// id of image
|
|
||||||
id string
|
|
||||||
// tags of image
|
|
||||||
tags []string
|
|
||||||
// layers stores all layers of image.
|
|
||||||
layers []image.LayerInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
func treeCmd(c *cliconfig.TreeValues) error {
|
func treeCmd(c *cliconfig.TreeValues) error {
|
||||||
args := c.InputArgs
|
args := c.InputArgs
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
@ -60,46 +50,33 @@ func treeCmd(c *cliconfig.TreeValues) error {
|
|||||||
return errors.Errorf("you must provide at most 1 argument")
|
return errors.Errorf("you must provide at most 1 argument")
|
||||||
}
|
}
|
||||||
|
|
||||||
runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
|
runtime, err := adapter.GetRuntime(&c.PodmanCommand)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "error creating libpod runtime")
|
return errors.Wrapf(err, "error creating libpod runtime")
|
||||||
}
|
}
|
||||||
defer runtime.Shutdown(false)
|
defer runtime.Shutdown(false)
|
||||||
|
imageInfo, layerInfoMap, img, err := runtime.Tree(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return printTree(imageInfo, layerInfoMap, img, c.WhatRequires)
|
||||||
|
}
|
||||||
|
|
||||||
img, err := runtime.ImageRuntime().NewFromLocal(args[0])
|
func printTree(imageInfo *image.InfoImage, layerInfoMap map[string]*image.LayerInfo, img *adapter.ContainerImage, whatRequires bool) error {
|
||||||
|
size, err := img.Size(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch map of image-layers, which is used for printing output.
|
fmt.Printf("Image ID: %s\n", imageInfo.ID[:12])
|
||||||
layerInfoMap, err := image.GetLayersMapWithImageInfo(runtime.ImageRuntime())
|
fmt.Printf("Tags:\t %s\n", imageInfo.Tags)
|
||||||
if err != nil {
|
|
||||||
return errors.Wrapf(err, "error while retriving layers of image %q", img.InputName)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create an imageInfo and fill the image and layer info
|
|
||||||
imageInfo := &infoImage{
|
|
||||||
id: img.ID(),
|
|
||||||
tags: img.Names(),
|
|
||||||
}
|
|
||||||
|
|
||||||
size, err := img.Size(context.Background())
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrapf(err, "error while retriving image size")
|
|
||||||
}
|
|
||||||
fmt.Printf("Image ID: %s\n", imageInfo.id[:12])
|
|
||||||
fmt.Printf("Tags:\t %s\n", imageInfo.tags)
|
|
||||||
fmt.Printf("Size:\t %v\n", units.HumanSizeWithPrecision(float64(*size), 4))
|
fmt.Printf("Size:\t %v\n", units.HumanSizeWithPrecision(float64(*size), 4))
|
||||||
fmt.Printf(fmt.Sprintf("Image Layers\n"))
|
fmt.Printf(fmt.Sprintf("Image Layers\n"))
|
||||||
|
|
||||||
if !c.WhatRequires {
|
if !whatRequires {
|
||||||
// fill imageInfo with layers associated with image.
|
// fill imageInfo with layers associated with image.
|
||||||
// the layers will be filled such that
|
// the layers will be filled such that
|
||||||
// (Start)RootLayer->...intermediate Parent Layer(s)-> TopLayer(End)
|
// (Start)RootLayer->...intermediate Parent Layer(s)-> TopLayer(End)
|
||||||
err := buildImageHierarchyMap(imageInfo, layerInfoMap, img.TopLayer())
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// Build output from imageInfo into buffer
|
// Build output from imageInfo into buffer
|
||||||
printImageHierarchy(imageInfo)
|
printImageHierarchy(imageInfo)
|
||||||
|
|
||||||
@ -108,30 +85,8 @@ func treeCmd(c *cliconfig.TreeValues) error {
|
|||||||
// the layers will be filled such that
|
// the layers will be filled such that
|
||||||
// (Start)TopLayer->...intermediate Child Layer(s)-> Child TopLayer(End)
|
// (Start)TopLayer->...intermediate Child Layer(s)-> Child TopLayer(End)
|
||||||
// (Forks)... intermediate Child Layer(s) -> Child Top Layer(End)
|
// (Forks)... intermediate Child Layer(s) -> Child Top Layer(End)
|
||||||
err := printImageChildren(layerInfoMap, img.TopLayer(), "", true)
|
return printImageChildren(layerInfoMap, img.TopLayer(), "", true)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stores hierarchy of images such that all parent layers using which image is built are stored in imageInfo
|
|
||||||
// Layers are added such that (Start)RootLayer->...intermediate Parent Layer(s)-> TopLayer(End)
|
|
||||||
func buildImageHierarchyMap(imageInfo *infoImage, layerMap map[string]*image.LayerInfo, layerID string) error {
|
|
||||||
if layerID == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
ll, ok := layerMap[layerID]
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("lookup error: layerid %s not found", layerID)
|
|
||||||
}
|
|
||||||
if err := buildImageHierarchyMap(imageInfo, layerMap, ll.ParentID); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
imageInfo.layers = append(imageInfo.layers, *ll)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,14 +130,14 @@ func printImageChildren(layerMap map[string]*image.LayerInfo, layerID string, pr
|
|||||||
}
|
}
|
||||||
|
|
||||||
// prints the layers info of image
|
// prints the layers info of image
|
||||||
func printImageHierarchy(imageInfo *infoImage) {
|
func printImageHierarchy(imageInfo *image.InfoImage) {
|
||||||
for count, l := range imageInfo.layers {
|
for count, l := range imageInfo.Layers {
|
||||||
var tags string
|
var tags string
|
||||||
intend := middleItem
|
intend := middleItem
|
||||||
if len(l.RepoTags) > 0 {
|
if len(l.RepoTags) > 0 {
|
||||||
tags = fmt.Sprintf(" Top Layer of: %s", l.RepoTags)
|
tags = fmt.Sprintf(" Top Layer of: %s", l.RepoTags)
|
||||||
}
|
}
|
||||||
if count == len(imageInfo.layers)-1 {
|
if count == len(imageInfo.Layers)-1 {
|
||||||
intend = lastItem
|
intend = lastItem
|
||||||
}
|
}
|
||||||
fmt.Printf("%s ID: %s Size: %7v%s\n", intend, l.ID[:12], units.HumanSizeWithPrecision(float64(l.Size), 4), tags)
|
fmt.Printf("%s ID: %s Size: %7v%s\n", intend, l.ID[:12], units.HumanSizeWithPrecision(float64(l.Size), 4), tags)
|
||||||
|
@ -68,7 +68,8 @@ type Image (
|
|||||||
virtualSize: int,
|
virtualSize: int,
|
||||||
containers: int,
|
containers: int,
|
||||||
labels: [string]string,
|
labels: [string]string,
|
||||||
isParent: bool
|
isParent: bool,
|
||||||
|
topLayer: string
|
||||||
)
|
)
|
||||||
|
|
||||||
# ImageHistory describes the returned structure from ImageHistory.
|
# ImageHistory describes the returned structure from ImageHistory.
|
||||||
@ -1161,8 +1162,15 @@ method LoadImage(name: string, inputFile: string, quiet: bool, deleteFile: bool)
|
|||||||
# GetEvents returns known libpod events filtered by the options provided.
|
# GetEvents returns known libpod events filtered by the options provided.
|
||||||
method GetEvents(filter: []string, since: string, until: string) -> (events: Event)
|
method GetEvents(filter: []string, since: string, until: string) -> (events: Event)
|
||||||
|
|
||||||
|
# Diff returns a diff between libpod objects
|
||||||
method Diff(name: string) -> (diffs: []DiffInfo)
|
method Diff(name: string) -> (diffs: []DiffInfo)
|
||||||
|
|
||||||
|
# GetLayersMapWithImageInfo is for the development of Podman and should not be used.
|
||||||
|
method GetLayersMapWithImageInfo() -> (layerMap: string)
|
||||||
|
|
||||||
|
# BuildImageHierarchyMap is for the development of Podman and should not be used.
|
||||||
|
method BuildImageHierarchyMap(name: string) -> (imageInfo: string)
|
||||||
|
|
||||||
# ImageNotFound means the image could not be found by the provided name or ID in local storage.
|
# ImageNotFound means the image could not be found by the provided name or ID in local storage.
|
||||||
error ImageNotFound (id: string, reason: string)
|
error ImageNotFound (id: string, reason: string)
|
||||||
|
|
||||||
|
@ -68,6 +68,16 @@ type Runtime struct {
|
|||||||
EventsLogFilePath string
|
EventsLogFilePath string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InfoImage keep information of Image along with all associated layers
|
||||||
|
type InfoImage struct {
|
||||||
|
// ID of image
|
||||||
|
ID string
|
||||||
|
// Tags of image
|
||||||
|
Tags []string
|
||||||
|
// Layers stores all layers of image.
|
||||||
|
Layers []LayerInfo
|
||||||
|
}
|
||||||
|
|
||||||
// ErrRepoTagNotFound is the error returned when the image id given doesn't match a rep tag in store
|
// ErrRepoTagNotFound is the error returned when the image id given doesn't match a rep tag in store
|
||||||
var ErrRepoTagNotFound = errors.New("unable to match user input to any specific repotag")
|
var ErrRepoTagNotFound = errors.New("unable to match user input to any specific repotag")
|
||||||
|
|
||||||
@ -1277,3 +1287,21 @@ func GetLayersMapWithImageInfo(imageruntime *Runtime) (map[string]*LayerInfo, er
|
|||||||
}
|
}
|
||||||
return layerInfoMap, nil
|
return layerInfoMap, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BuildImageHierarchyMap stores hierarchy of images such that all parent layers using which image is built are stored in imageInfo
|
||||||
|
// Layers are added such that (Start)RootLayer->...intermediate Parent Layer(s)-> TopLayer(End)
|
||||||
|
func BuildImageHierarchyMap(imageInfo *InfoImage, layerMap map[string]*LayerInfo, layerID string) error {
|
||||||
|
if layerID == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
ll, ok := layerMap[layerID]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("lookup error: layerid %s not found", layerID)
|
||||||
|
}
|
||||||
|
if err := BuildImageHierarchyMap(imageInfo, layerMap, ll.ParentID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
imageInfo.Layers = append(imageInfo.Layers, *ll)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
34
pkg/adapter/images.go
Normal file
34
pkg/adapter/images.go
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// +build !remoteclient
|
||||||
|
|
||||||
|
package adapter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/containers/libpod/cmd/podman/cliconfig"
|
||||||
|
"github.com/containers/libpod/libpod/image"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Tree ...
|
||||||
|
func (r *LocalRuntime) Tree(c *cliconfig.TreeValues) (*image.InfoImage, map[string]*image.LayerInfo, *ContainerImage, error) {
|
||||||
|
img, err := r.NewImageFromLocal(c.InputArgs[0])
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch map of image-layers, which is used for printing output.
|
||||||
|
layerInfoMap, err := image.GetLayersMapWithImageInfo(r.Runtime.ImageRuntime())
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, errors.Wrapf(err, "error while retrieving layers of image %q", img.InputName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create an imageInfo and fill the image and layer info
|
||||||
|
imageInfo := &image.InfoImage{
|
||||||
|
ID: img.ID(),
|
||||||
|
Tags: img.Names(),
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := image.BuildImageHierarchyMap(imageInfo, layerInfoMap, img.TopLayer()); err != nil {
|
||||||
|
return nil, nil, nil, err
|
||||||
|
}
|
||||||
|
return imageInfo, layerInfoMap, img, nil
|
||||||
|
}
|
@ -6,8 +6,11 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/containers/libpod/cmd/podman/cliconfig"
|
||||||
iopodman "github.com/containers/libpod/cmd/podman/varlink"
|
iopodman "github.com/containers/libpod/cmd/podman/varlink"
|
||||||
|
"github.com/containers/libpod/libpod/image"
|
||||||
"github.com/containers/libpod/pkg/inspect"
|
"github.com/containers/libpod/pkg/inspect"
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Inspect returns returns an ImageData struct from over a varlink connection
|
// Inspect returns returns an ImageData struct from over a varlink connection
|
||||||
@ -22,3 +25,32 @@ func (i *ContainerImage) Inspect(ctx context.Context) (*inspect.ImageData, error
|
|||||||
}
|
}
|
||||||
return &data, nil
|
return &data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tree ...
|
||||||
|
func (r *LocalRuntime) Tree(c *cliconfig.TreeValues) (*image.InfoImage, map[string]*image.LayerInfo, *ContainerImage, error) {
|
||||||
|
layerInfoMap := make(map[string]*image.LayerInfo)
|
||||||
|
imageInfo := &image.InfoImage{}
|
||||||
|
|
||||||
|
img, err := r.NewImageFromLocal(c.InputArgs[0])
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
reply, err := iopodman.GetLayersMapWithImageInfo().Call(r.Conn)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, errors.Wrap(err, "failed to obtain image layers")
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal([]byte(reply), &layerInfoMap); err != nil {
|
||||||
|
return nil, nil, nil, errors.Wrap(err, "failed to unmarshal image layers")
|
||||||
|
}
|
||||||
|
|
||||||
|
reply, err = iopodman.BuildImageHierarchyMap().Call(r.Conn, c.InputArgs[0])
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, errors.Wrap(err, "failed to get build image map")
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal([]byte(reply), imageInfo); err != nil {
|
||||||
|
return nil, nil, nil, errors.Wrap(err, "failed to unmarshal build image map")
|
||||||
|
}
|
||||||
|
|
||||||
|
return imageInfo, layerInfoMap, img, nil
|
||||||
|
}
|
||||||
|
@ -82,6 +82,7 @@ type remoteImage struct {
|
|||||||
Digest digest.Digest
|
Digest digest.Digest
|
||||||
isParent bool
|
isParent bool
|
||||||
Runtime *LocalRuntime
|
Runtime *LocalRuntime
|
||||||
|
TopLayer string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Container ...
|
// Container ...
|
||||||
@ -147,6 +148,7 @@ func imageInListToContainerImage(i iopodman.Image, name string, runtime *LocalRu
|
|||||||
Names: i.RepoTags,
|
Names: i.RepoTags,
|
||||||
isParent: i.IsParent,
|
isParent: i.IsParent,
|
||||||
Runtime: runtime,
|
Runtime: runtime,
|
||||||
|
TopLayer: i.TopLayer,
|
||||||
}
|
}
|
||||||
return &ContainerImage{ri}, nil
|
return &ContainerImage{ri}, nil
|
||||||
}
|
}
|
||||||
@ -280,6 +282,11 @@ func (ci *ContainerImage) Dangling() bool {
|
|||||||
return len(ci.Names()) == 0
|
return len(ci.Names()) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TopLayer returns an images top layer as a string
|
||||||
|
func (ci *ContainerImage) TopLayer() string {
|
||||||
|
return ci.remoteImage.TopLayer
|
||||||
|
}
|
||||||
|
|
||||||
// TagImage ...
|
// TagImage ...
|
||||||
func (ci *ContainerImage) TagImage(tag string) error {
|
func (ci *ContainerImage) TagImage(tag string) error {
|
||||||
_, err := iopodman.TagImage().Call(ci.Runtime.Conn, ci.ID(), tag)
|
_, err := iopodman.TagImage().Call(ci.Runtime.Conn, ci.ID(), tag)
|
||||||
|
@ -103,6 +103,7 @@ func (i *LibpodAPI) GetImage(call iopodman.VarlinkCall, id string) error {
|
|||||||
VirtualSize: newImage.VirtualSize,
|
VirtualSize: newImage.VirtualSize,
|
||||||
Containers: int64(len(containers)),
|
Containers: int64(len(containers)),
|
||||||
Labels: labels,
|
Labels: labels,
|
||||||
|
TopLayer: newImage.TopLayer(),
|
||||||
}
|
}
|
||||||
return call.ReplyGetImage(il)
|
return call.ReplyGetImage(il)
|
||||||
}
|
}
|
||||||
@ -923,3 +924,40 @@ func (i *LibpodAPI) Diff(call iopodman.VarlinkCall, name string) error {
|
|||||||
}
|
}
|
||||||
return call.ReplyDiff(response)
|
return call.ReplyDiff(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetLayersMapWithImageInfo is a development only endpoint to obtain layer information for an image.
|
||||||
|
func (i *LibpodAPI) GetLayersMapWithImageInfo(call iopodman.VarlinkCall) error {
|
||||||
|
layerInfo, err := image.GetLayersMapWithImageInfo(i.Runtime.ImageRuntime())
|
||||||
|
if err != nil {
|
||||||
|
return call.ReplyErrorOccurred(err.Error())
|
||||||
|
}
|
||||||
|
b, err := json.Marshal(layerInfo)
|
||||||
|
if err != nil {
|
||||||
|
return call.ReplyErrorOccurred(err.Error())
|
||||||
|
}
|
||||||
|
return call.ReplyGetLayersMapWithImageInfo(string(b))
|
||||||
|
}
|
||||||
|
|
||||||
|
// BuildImageHierarchyMap ...
|
||||||
|
func (i *LibpodAPI) BuildImageHierarchyMap(call iopodman.VarlinkCall, name string) error {
|
||||||
|
img, err := i.Runtime.ImageRuntime().NewFromLocal(name)
|
||||||
|
if err != nil {
|
||||||
|
return call.ReplyErrorOccurred(err.Error())
|
||||||
|
}
|
||||||
|
imageInfo := &image.InfoImage{
|
||||||
|
ID: img.ID(),
|
||||||
|
Tags: img.Names(),
|
||||||
|
}
|
||||||
|
layerInfo, err := image.GetLayersMapWithImageInfo(i.Runtime.ImageRuntime())
|
||||||
|
if err != nil {
|
||||||
|
return call.ReplyErrorOccurred(err.Error())
|
||||||
|
}
|
||||||
|
if err := image.BuildImageHierarchyMap(imageInfo, layerInfo, img.TopLayer()); err != nil {
|
||||||
|
return call.ReplyErrorOccurred(err.Error())
|
||||||
|
}
|
||||||
|
b, err := json.Marshal(imageInfo)
|
||||||
|
if err != nil {
|
||||||
|
return call.ReplyErrorOccurred(err.Error())
|
||||||
|
}
|
||||||
|
return call.ReplyBuildImageHierarchyMap(string(b))
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user