diff options
-rwxr-xr-x | API.md | 359 | ||||
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | cmd/podman/commands.go | 7 | ||||
-rw-r--r-- | cmd/podman/commands_remoteclient.go | 2 | ||||
-rw-r--r-- | cmd/podman/image.go | 1 | ||||
-rw-r--r-- | cmd/podman/images.go | 6 | ||||
-rw-r--r-- | cmd/podman/main.go | 1 | ||||
-rw-r--r-- | cmd/podman/port.go | 7 | ||||
-rw-r--r-- | cmd/podman/push.go | 15 | ||||
-rw-r--r-- | cmd/podman/shared/container.go | 7 | ||||
-rw-r--r-- | cmd/podman/varlink.go | 2 | ||||
-rw-r--r-- | cmd/podman/varlink/io.podman.varlink | 133 | ||||
-rw-r--r-- | cmd/podman/varlink_dummy.go | 10 | ||||
-rw-r--r-- | cmd/podman/volume_inspect.go | 22 | ||||
-rw-r--r-- | cmd/podman/volume_ls.go | 42 | ||||
-rw-r--r-- | completions/bash/podman | 1 | ||||
-rwxr-xr-x | hack/get_ci_vm.sh | 33 | ||||
-rw-r--r-- | libpod/adapter/runtime.go | 66 | ||||
-rw-r--r-- | libpod/adapter/runtime_remote.go | 93 | ||||
-rw-r--r-- | libpod/adapter/volumes_remote.go | 33 | ||||
-rw-r--r-- | libpod/container.go | 12 | ||||
-rw-r--r-- | libpod/image/utils.go | 17 | ||||
-rw-r--r-- | libpod/kube.go | 6 | ||||
-rw-r--r-- | pkg/varlinkapi/containers.go | 29 | ||||
-rw-r--r-- | pkg/varlinkapi/images.go | 103 | ||||
-rw-r--r-- | pkg/varlinkapi/system.go | 25 | ||||
-rw-r--r-- | pkg/varlinkapi/util.go | 8 | ||||
-rw-r--r-- | pkg/varlinkapi/volumes.go | 36 |
28 files changed, 646 insertions, 433 deletions
@@ -3,9 +3,7 @@ Podman Service Interface and API description. The master version of this docume in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in the upstream libpod repository. ## Index -[func AttachToContainer() NotImplemented](#AttachToContainer) - -[func BuildImage(build: BuildInfo) BuildResponse](#BuildImage) +[func BuildImage(build: BuildInfo) MoreResponse](#BuildImage) [func Commit(name: string, image_name: string, changes: []string, author: string, message: string, pause: bool, manifestType: string) string](#Commit) @@ -27,8 +25,6 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in [func CreateContainer(create: Create) string](#CreateContainer) -[func CreateImage() NotImplemented](#CreateImage) - [func CreatePod(create: PodCreate) string](#CreatePod) [func DeleteStoppedContainers() []string](#DeleteStoppedContainers) @@ -39,19 +35,15 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in [func ExportImage(name: string, destination: string, compress: bool, tags: []string) string](#ExportImage) -[func GenerateKube() NotImplemented](#GenerateKube) - -[func GenerateKubeService() NotImplemented](#GenerateKubeService) - [func GetAttachSockets(name: string) Sockets](#GetAttachSockets) -[func GetContainer(name: string) ListContainerData](#GetContainer) +[func GetContainer(id: string) Container](#GetContainer) [func GetContainerLogs(name: string) []string](#GetContainerLogs) [func GetContainerStats(name: string) ContainerStats](#GetContainerStats) -[func GetImage(name: string) ImageInList](#GetImage) +[func GetImage(id: string) Image](#GetImage) [func GetInfo() PodmanInfo](#GetInfo) @@ -59,7 +51,9 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in [func GetPodStats(name: string) string, ContainerStats](#GetPodStats) -[func GetVersion() Version](#GetVersion) +[func GetVersion() string, string, string, string, string, int](#GetVersion) + +[func GetVolumes(args: []string, all: bool) Volume](#GetVolumes) [func HistoryImage(name: string) ImageHistory](#HistoryImage) @@ -67,7 +61,7 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in [func ImagesPrune(all: bool) []string](#ImagesPrune) -[func ImportImage(source: string, reference: string, message: string, changes: []string) string](#ImportImage) +[func ImportImage(source: string, reference: string, message: string, changes: []string, delete: bool) string](#ImportImage) [func InspectContainer(name: string) string](#InspectContainer) @@ -83,13 +77,11 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in [func ListContainerMounts() map[string]](#ListContainerMounts) -[func ListContainerPorts(name: string) NotImplemented](#ListContainerPorts) - [func ListContainerProcesses(name: string, opts: []string) []string](#ListContainerProcesses) -[func ListContainers() ListContainerData](#ListContainers) +[func ListContainers() Container](#ListContainers) -[func ListImages() ImageInList](#ListImages) +[func ListImages() Image](#ListImages) [func ListPods() ListPodData](#ListPods) @@ -99,11 +91,11 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in [func PausePod(name: string) string](#PausePod) -[func Ping() StringResponse](#Ping) - [func PullImage(name: string, certDir: string, creds: string, signaturePolicy: string, tlsVerify: bool) string](#PullImage) -[func PushImage(name: string, tag: string, tlsverify: bool, signaturePolicy: string, creds: string, certDir: string, compress: bool, format: string, removeSignatures: bool, signBy: string) string](#PushImage) +[func PushImage(name: string, tag: string, tlsverify: bool, signaturePolicy: string, creds: string, certDir: string, compress: bool, format: string, removeSignatures: bool, signBy: string) MoreResponse](#PushImage) + +[func ReceiveFile(path: string, delete: bool) int](#ReceiveFile) [func RemoveContainer(name: string, force: bool) string](#RemoveContainer) @@ -111,17 +103,13 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in [func RemovePod(name: string, force: bool) string](#RemovePod) -[func RenameContainer() NotImplemented](#RenameContainer) - -[func ReplayKube() NotImplemented](#ReplayKube) - -[func ResizeContainerTty() NotImplemented](#ResizeContainerTty) - [func RestartContainer(name: string, timeout: int) string](#RestartContainer) [func RestartPod(name: string) string](#RestartPod) -[func SearchImage(name: string, limit: int) ImageSearch](#SearchImage) +[func SearchImages(query: string, limit: ) ImageSearchResult](#SearchImages) + +[func SendFile(type: string, length: int) string](#SendFile) [func StartContainer(name: string) string](#StartContainer) @@ -133,23 +121,21 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in [func TagImage(name: string, tagged: string) string](#TagImage) -[func TopPod() NotImplemented](#TopPod) - [func UnmountContainer(name: string, force: bool) ](#UnmountContainer) [func UnpauseContainer(name: string) string](#UnpauseContainer) [func UnpausePod(name: string) string](#UnpausePod) -[func UpdateContainer() NotImplemented](#UpdateContainer) +[func VolumeCreate(options: VolumeCreateOpts) string](#VolumeCreate) -[func WaitContainer(name: string) int](#WaitContainer) +[func VolumeRemove(options: VolumeRemoveOpts) []string](#VolumeRemove) -[func WaitPod() NotImplemented](#WaitPod) +[func WaitContainer(name: string) int](#WaitContainer) [type BuildInfo](#BuildInfo) -[type BuildResponse](#BuildResponse) +[type Container](#Container) [type ContainerChanges](#ContainerChanges) @@ -169,11 +155,11 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in [type IDMappingOptions](#IDMappingOptions) -[type ImageHistory](#ImageHistory) +[type Image](#Image) -[type ImageInList](#ImageInList) +[type ImageHistory](#ImageHistory) -[type ImageSearch](#ImageSearch) +[type ImageSearchResult](#ImageSearchResult) [type InfoDistribution](#InfoDistribution) @@ -185,12 +171,12 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in [type InfoStore](#InfoStore) -[type ListContainerData](#ListContainerData) - [type ListPodContainerInfo](#ListPodContainerInfo) [type ListPodData](#ListPodData) +[type MoreResponse](#MoreResponse) + [type NotImplemented](#NotImplemented) [type PodContainerErrorData](#PodContainerErrorData) @@ -205,7 +191,11 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in [type StringResponse](#StringResponse) -[type Version](#Version) +[type Volume](#Volume) + +[type VolumeCreateOpts](#VolumeCreateOpts) + +[type VolumeRemoveOpts](#VolumeRemoveOpts) [error ContainerNotFound](#ContainerNotFound) @@ -224,17 +214,12 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in [error RuntimeError](#RuntimeError) ## Methods -### <a name="AttachToContainer"></a>func AttachToContainer -<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> - -method AttachToContainer() [NotImplemented](#NotImplemented)</div> -This method has not be implemented yet. ### <a name="BuildImage"></a>func BuildImage <div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> -method BuildImage(build: [BuildInfo](#BuildInfo)) [BuildResponse](#BuildResponse)</div> +method BuildImage(build: [BuildInfo](#BuildInfo)) [MoreResponse](#MoreResponse)</div> 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 [BuildResponse](#BuildResponse) 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. ### <a name="Commit"></a>func Commit <div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> @@ -316,11 +301,6 @@ $ varlink call unix:/run/podman/io.podman/io.podman.CreateContainer '{"create": "container": "8759dafbc0a4dc3bcfb57eeb72e4331eb73c5cc09ab968e65ce45b9ad5c4b6bb" } ~~~ -### <a name="CreateImage"></a>func CreateImage -<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> - -method CreateImage() [NotImplemented](#NotImplemented)</div> -This function is not implemented yet. ### <a name="CreatePod"></a>func CreatePod <div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> @@ -398,18 +378,6 @@ a booleon option to force compression. It also takes in a string array of tags tags of the same image to a tarball (each tag should be of the form <image>:<tag>). Upon completion, the ID of the image is returned. If the image cannot be found in local storage, an [ImageNotFound](#ImageNotFound) error will be returned. See also [ImportImage](ImportImage). -### <a name="GenerateKube"></a>func GenerateKube -<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> - -method GenerateKube() [NotImplemented](#NotImplemented)</div> -GenerateKube generates a Kubernetes v1 Pod description of a Podman container or pod -and its containers. The description is in YAML. See also [ReplayKube](ReplayKube). -### <a name="GenerateKubeService"></a>func GenerateKubeService -<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> - -method GenerateKubeService() [NotImplemented](#NotImplemented)</div> -GenerateKubeService generates a Kubernetes v1 Service description of a Podman container or pod -and its containers. The description is in YAML. See also [GenerateKube](GenerateKube). ### <a name="GetAttachSockets"></a>func GetAttachSockets <div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> @@ -432,10 +400,11 @@ $ varlink call -m unix:/run/io.podman/io.podman.GetAttachSockets '{"name": "b762 ### <a name="GetContainer"></a>func GetContainer <div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> -method GetContainer(name: [string](https://godoc.org/builtin#string)) [ListContainerData](#ListContainerData)</div> -GetContainer takes a name or ID of a container and returns single ListContainerData -structure. A [ContainerNotFound](#ContainerNotFound) error will be returned if the container cannot be found. -See also [ListContainers](ListContainers) and [InspectContainer](#InspectContainer). +method GetContainer(id: [string](https://godoc.org/builtin#string)) [Container](#Container)</div> +GetContainer returns information about a single container. If a container +with the given id doesn't exist, a [ContainerNotFound](#ContainerNotFound) +error will be returned. See also [ListContainers](ListContainers) and +[InspectContainer](#InspectContainer). ### <a name="GetContainerLogs"></a>func GetContainerLogs <div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> @@ -476,9 +445,9 @@ $ varlink call -m unix:/run/podman/io.podman/io.podman.GetContainerStats '{"name ### <a name="GetImage"></a>func GetImage <div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> -method GetImage(name: [string](https://godoc.org/builtin#string)) [ImageInList](#ImageInList)</div> -GetImage returns a single image in an [ImageInList](#ImageInList) struct. You must supply an image name as a string. -If the image cannot be found, an [ImageNotFound](#ImageNotFound) error will be returned. +method GetImage(id: [string](https://godoc.org/builtin#string)) [Image](#Image)</div> +GetImage returns information about a single image in storage. +If the image caGetImage returns be found, [ImageNotFound](#ImageNotFound) will be returned. ### <a name="GetInfo"></a>func GetInfo <div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> @@ -553,9 +522,13 @@ $ varlink call unix:/run/podman/io.podman/io.podman.GetPodStats '{"name": "7f62b ### <a name="GetVersion"></a>func GetVersion <div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> -method GetVersion() [Version](#Version)</div> -GetVersion returns a Version structure describing the libpod setup on their -system. +method GetVersion() [string](https://godoc.org/builtin#string), [string](https://godoc.org/builtin#string), [string](https://godoc.org/builtin#string), [string](https://godoc.org/builtin#string), [string](https://godoc.org/builtin#string), [int](https://godoc.org/builtin#int)</div> +GetVersion returns version and build information of the podman service +### <a name="GetVolumes"></a>func GetVolumes +<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> + +method GetVolumes(args: [[]string](#[]string), all: [bool](https://godoc.org/builtin#bool)) [Volume](#Volume)</div> + ### <a name="HistoryImage"></a>func HistoryImage <div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> @@ -586,7 +559,7 @@ the IDs of the removed images are returned. ### <a name="ImportImage"></a>func ImportImage <div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> -method ImportImage(source: [string](https://godoc.org/builtin#string), reference: [string](https://godoc.org/builtin#string), message: [string](https://godoc.org/builtin#string), changes: [[]string](#[]string)) [string](https://godoc.org/builtin#string)</div> +method ImportImage(source: [string](https://godoc.org/builtin#string), reference: [string](https://godoc.org/builtin#string), message: [string](https://godoc.org/builtin#string), changes: [[]string](#[]string), delete: [bool](https://godoc.org/builtin#bool)) [string](https://godoc.org/builtin#string)</div> ImportImage imports an image from a source (like tarball) into local storage. The image can have additional descriptions added to it using the message and changes options. See also [ExportImage](ExportImage). ### <a name="InspectContainer"></a>func InspectContainer @@ -656,11 +629,6 @@ $ varlink call unix:/run/podman/io.podman/io.podman.ListContainerMounts } } ~~~ -### <a name="ListContainerPorts"></a>func ListContainerPorts -<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> - -method ListContainerPorts(name: [string](https://godoc.org/builtin#string)) [NotImplemented](#NotImplemented)</div> -This function is not implemented yet. ### <a name="ListContainerProcesses"></a>func ListContainerProcesses <div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> @@ -684,15 +652,15 @@ $ varlink call -m unix:/run/podman/io.podman/io.podman.ListContainerProcesses '{ ### <a name="ListContainers"></a>func ListContainers <div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> -method ListContainers() [ListContainerData](#ListContainerData)</div> -ListContainers returns a list of containers in no particular order. There are -returned as an array of ListContainerData structs. See also [GetContainer](#GetContainer). +method ListContainers() [Container](#Container)</div> +ListContainers returns information about all containers. +See also [GetContainer](#GetContainer). ### <a name="ListImages"></a>func ListImages <div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> -method ListImages() [ImageInList](#ImageInList)</div> -ListImages returns an array of ImageInList structures which provide basic information about -an image currently in storage. See also [InspectImage](InspectImage). +method ListImages() [Image](#Image)</div> +ListImages returns information about the images that are currently in storage. +See also [InspectImage](InspectImage). ### <a name="ListPods"></a>func ListPods <div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> @@ -778,20 +746,6 @@ $ varlink call -m unix:/run/podman/io.podman/io.podman.PausePod '{"name": "fooba "pod": "1840835294cf076a822e4e12ba4152411f131bd869e7f6a4e8b16df9b0ea5c7f" } ~~~ -### <a name="Ping"></a>func Ping -<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> - -method Ping() [StringResponse](#StringResponse)</div> -Ping provides a response for developers to ensure their varlink setup is working. -#### Example -~~~ -$ varlink call -m unix:/run/podman/io.podman/io.podman.Ping -{ - "ping": { - "message": "OK" - } -} -~~~ ### <a name="PullImage"></a>func PullImage <div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> @@ -808,11 +762,16 @@ $ varlink call -m unix:/run/podman/io.podman/io.podman.PullImage '{"name": "regi ### <a name="PushImage"></a>func PushImage <div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> -method PushImage(name: [string](https://godoc.org/builtin#string), tag: [string](https://godoc.org/builtin#string), tlsverify: [bool](https://godoc.org/builtin#bool), signaturePolicy: [string](https://godoc.org/builtin#string), creds: [string](https://godoc.org/builtin#string), certDir: [string](https://godoc.org/builtin#string), compress: [bool](https://godoc.org/builtin#bool), format: [string](https://godoc.org/builtin#string), removeSignatures: [bool](https://godoc.org/builtin#bool), signBy: [string](https://godoc.org/builtin#string)) [string](https://godoc.org/builtin#string)</div> +method PushImage(name: [string](https://godoc.org/builtin#string), tag: [string](https://godoc.org/builtin#string), tlsverify: [bool](https://godoc.org/builtin#bool), signaturePolicy: [string](https://godoc.org/builtin#string), creds: [string](https://godoc.org/builtin#string), certDir: [string](https://godoc.org/builtin#string), compress: [bool](https://godoc.org/builtin#bool), format: [string](https://godoc.org/builtin#string), removeSignatures: [bool](https://godoc.org/builtin#bool), signBy: [string](https://godoc.org/builtin#string)) [MoreResponse](#MoreResponse)</div> PushImage takes three input arguments: the name or ID of an image, the fully-qualified destination name of the image, and a boolean as to whether tls-verify should be used (with false disabling TLS, not affecting the default behavior). It will return an [ImageNotFound](#ImageNotFound) error if -the image cannot be found in local storage; otherwise the ID of the image will be returned on success. +the image cannot be found in local storage; otherwise it will return a [MoreResponse](#MoreResponse) +### <a name="ReceiveFile"></a>func ReceiveFile +<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> + +method ReceiveFile(path: [string](https://godoc.org/builtin#string), delete: [bool](https://godoc.org/builtin#bool)) [int](https://godoc.org/builtin#int)</div> + ### <a name="RemoveContainer"></a>func RemoveContainer <div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> @@ -859,22 +818,6 @@ $ varlink call -m unix:/run/podman/io.podman/io.podman.RemovePod '{"name": "62f4 "pod": "62f4fd98cb57f529831e8f90610e54bba74bd6f02920ffb485e15376ed365c20" } ~~~ -### <a name="RenameContainer"></a>func RenameContainer -<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> - -method RenameContainer() [NotImplemented](#NotImplemented)</div> -This method has not be implemented yet. -### <a name="ReplayKube"></a>func ReplayKube -<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> - -method ReplayKube() [NotImplemented](#NotImplemented)</div> -ReplayKube recreates a pod and its containers based on a Kubernetes v1 Pod description (in YAML) -like that created by GenerateKube. See also [GenerateKube](GenerateKube). -### <a name="ResizeContainerTty"></a>func ResizeContainerTty -<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> - -method ResizeContainerTty() [NotImplemented](#NotImplemented)</div> -This method has not be implemented yet. ### <a name="RestartContainer"></a>func RestartContainer <div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> @@ -900,13 +843,18 @@ $ varlink call -m unix:/run/podman/io.podman/io.podman.RestartPod '{"name": "135 "pod": "135d71b9495f7c3967f536edad57750bfdb569336cd107d8aabab45565ffcfb6" } ~~~ -### <a name="SearchImage"></a>func SearchImage +### <a name="SearchImages"></a>func SearchImages +<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> + +method SearchImages(query: [string](https://godoc.org/builtin#string), limit: [](#)) [ImageSearchResult](#ImageSearchResult)</div> +SearchImages searches available registries for images that contain the +contents of "query" in their name. If "limit" is given, limits the amount of +search results per registry. +### <a name="SendFile"></a>func SendFile <div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> -method SearchImage(name: [string](https://godoc.org/builtin#string), limit: [int](https://godoc.org/builtin#int)) [ImageSearch](#ImageSearch)</div> -SearchImage takes the string of an image name and a limit of searches from each registries to be returned. SearchImage -will then use a glob-like match to find the image you are searching for. The images are returned in an array of -ImageSearch structures which contain information about the image as well as its fully-qualified name. +method SendFile(type: [string](https://godoc.org/builtin#string), length: [int](https://godoc.org/builtin#int)) [string](https://godoc.org/builtin#string)</div> + ### <a name="StartContainer"></a>func StartContainer <div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> @@ -968,11 +916,6 @@ $ varlink call -m unix:/run/podman/io.podman/io.podman.StopPod '{"name": "135d71 method TagImage(name: [string](https://godoc.org/builtin#string), tagged: [string](https://godoc.org/builtin#string)) [string](https://godoc.org/builtin#string)</div> TagImage takes the name or ID of an image in local storage as well as the desired tag name. If the image cannot be found, an [ImageNotFound](#ImageNotFound) error will be returned; otherwise, the ID of the image is returned on success. -### <a name="TopPod"></a>func TopPod -<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> - -method TopPod() [NotImplemented](#NotImplemented)</div> -This method has not been implemented yet. ### <a name="UnmountContainer"></a>func UnmountContainer <div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> @@ -1007,11 +950,16 @@ $ varlink call -m unix:/run/podman/io.podman/io.podman.UnpausePod '{"name": "foo "pod": "1840835294cf076a822e4e12ba4152411f131bd869e7f6a4e8b16df9b0ea5c7f" } ~~~ -### <a name="UpdateContainer"></a>func UpdateContainer +### <a name="VolumeCreate"></a>func VolumeCreate +<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> + +method VolumeCreate(options: [VolumeCreateOpts](#VolumeCreateOpts)) [string](https://godoc.org/builtin#string)</div> + +### <a name="VolumeRemove"></a>func VolumeRemove <div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> -method UpdateContainer() [NotImplemented](#NotImplemented)</div> -This method has not be implemented yet. +method VolumeRemove(options: [VolumeRemoveOpts](#VolumeRemoveOpts)) [[]string](#[]string)</div> + ### <a name="WaitContainer"></a>func WaitContainer <div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> @@ -1019,11 +967,6 @@ method WaitContainer(name: [string](https://godoc.org/builtin#string)) [int](htt WaitContainer takes the name or ID of a container and waits until the container stops. Upon stopping, the return code of the container is returned. If the container container cannot be found by ID or name, a [ContainerNotFound](#ContainerNotFound) error is returned. -### <a name="WaitPod"></a>func WaitPod -<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> - -method WaitPod() [NotImplemented](#NotImplemented)</div> -This method has not be implemented yet. ## Types ### <a name="BuildInfo"></a>type BuildInfo @@ -1076,13 +1019,39 @@ annotations [[]string](#[]string) build_args [map[string]](#map[string]) image_format [string](https://godoc.org/builtin#string) -### <a name="BuildResponse"></a>type BuildResponse +### <a name="Container"></a>type Container -BuildResponse is used to describe the responses for building images -logs [[]string](#[]string) id [string](https://godoc.org/builtin#string) + +image [string](https://godoc.org/builtin#string) + +imageid [string](https://godoc.org/builtin#string) + +command [[]string](#[]string) + +createdat [string](https://godoc.org/builtin#string) + +runningfor [string](https://godoc.org/builtin#string) + +status [string](https://godoc.org/builtin#string) + +ports [ContainerPortMappings](#ContainerPortMappings) + +rootfssize [int](https://godoc.org/builtin#int) + +rwsize [int](https://godoc.org/builtin#int) + +names [string](https://godoc.org/builtin#string) + +labels [map[string]](#map[string]) + +mounts [ContainerMount](#ContainerMount) + +containerrunning [bool](https://godoc.org/builtin#bool) + +namespaces [ContainerNameSpace](#ContainerNameSpace) ### <a name="ContainerChanges"></a>type ContainerChanges ContainerChanges describes the return struct for ListContainerChanges @@ -1366,25 +1335,9 @@ host_gid_mapping [bool](https://godoc.org/builtin#bool) uid_map [IDMap](#IDMap) gid_map [IDMap](#IDMap) -### <a name="ImageHistory"></a>type ImageHistory - -ImageHistory describes the returned structure from ImageHistory. - -id [string](https://godoc.org/builtin#string) - -created [string](https://godoc.org/builtin#string) - -createdBy [string](https://godoc.org/builtin#string) - -tags [[]string](#[]string) +### <a name="Image"></a>type Image -size [int](https://godoc.org/builtin#int) - -comment [string](https://godoc.org/builtin#string) -### <a name="ImageInList"></a>type ImageInList -ImageInList describes the structure that is returned in -ListImages. id [string](https://godoc.org/builtin#string) @@ -1405,10 +1358,24 @@ containers [int](https://godoc.org/builtin#int) labels [map[string]](#map[string]) isParent [bool](https://godoc.org/builtin#bool) -### <a name="ImageSearch"></a>type ImageSearch +### <a name="ImageHistory"></a>type ImageHistory + +ImageHistory describes the returned structure from ImageHistory. + +id [string](https://godoc.org/builtin#string) -ImageSearch is the returned structure for SearchImage. It is returned -in array form. +created [string](https://godoc.org/builtin#string) + +createdBy [string](https://godoc.org/builtin#string) + +tags [[]string](#[]string) + +size [int](https://godoc.org/builtin#int) + +comment [string](https://godoc.org/builtin#string) +### <a name="ImageSearchResult"></a>type ImageSearchResult + +Represents a single search result from SearchImages description [string](https://godoc.org/builtin#string) @@ -1490,39 +1457,6 @@ graph_root [string](https://godoc.org/builtin#string) graph_status [InfoGraphStatus](#InfoGraphStatus) run_root [string](https://godoc.org/builtin#string) -### <a name="ListContainerData"></a>type ListContainerData - -ListContainerData is the returned struct for an individual container - -id [string](https://godoc.org/builtin#string) - -image [string](https://godoc.org/builtin#string) - -imageid [string](https://godoc.org/builtin#string) - -command [[]string](#[]string) - -createdat [string](https://godoc.org/builtin#string) - -runningfor [string](https://godoc.org/builtin#string) - -status [string](https://godoc.org/builtin#string) - -ports [ContainerPortMappings](#ContainerPortMappings) - -rootfssize [int](https://godoc.org/builtin#int) - -rwsize [int](https://godoc.org/builtin#int) - -names [string](https://godoc.org/builtin#string) - -labels [map[string]](#map[string]) - -mounts [ContainerMount](#ContainerMount) - -containerrunning [bool](https://godoc.org/builtin#bool) - -namespaces [ContainerNameSpace](#ContainerNameSpace) ### <a name="ListPodContainerInfo"></a>type ListPodContainerInfo ListPodContainerInfo is a returned struct for describing containers @@ -1552,6 +1486,13 @@ labels [map[string]](#map[string]) numberofcontainers [string](https://godoc.org/builtin#string) containersinfo [ListPodContainerInfo](#ListPodContainerInfo) +### <a name="MoreResponse"></a>type MoreResponse + +MoreResponse is a struct for when responses from varlink requires longer output + +logs [[]string](#[]string) + +id [string](https://godoc.org/builtin#string) ### <a name="NotImplemented"></a>type NotImplemented @@ -1639,21 +1580,41 @@ control_socket [string](https://godoc.org/builtin#string) message [string](https://godoc.org/builtin#string) -### <a name="Version"></a>type Version +### <a name="Volume"></a>type Volume -Version is the structure returned by GetVersion -version [string](https://godoc.org/builtin#string) -go_version [string](https://godoc.org/builtin#string) +name [string](https://godoc.org/builtin#string) -git_commit [string](https://godoc.org/builtin#string) +labels [map[string]](#map[string]) + +mountPoint [string](https://godoc.org/builtin#string) + +driver [string](https://godoc.org/builtin#string) + +options [map[string]](#map[string]) + +scope [string](https://godoc.org/builtin#string) +### <a name="VolumeCreateOpts"></a>type VolumeCreateOpts -built [int](https://godoc.org/builtin#int) -os_arch [string](https://godoc.org/builtin#string) -remote_api_version [int](https://godoc.org/builtin#int) +volumeName [string](https://godoc.org/builtin#string) + +driver [string](https://godoc.org/builtin#string) + +labels [map[string]](#map[string]) + +options [map[string]](#map[string]) +### <a name="VolumeRemoveOpts"></a>type VolumeRemoveOpts + + + +volumes [[]string](#[]string) + +all [bool](https://godoc.org/builtin#bool) + +force [bool](https://godoc.org/builtin#bool) ## Errors ### <a name="ContainerNotFound"></a>type ContainerNotFound @@ -34,7 +34,7 @@ SELINUXOPT ?= $(shell test -x /usr/sbin/selinuxenabled && selinuxenabled && echo PACKAGES ?= $(shell $(GO) list -tags "${BUILDTAGS}" ./... | grep -v github.com/containers/libpod/vendor | grep -v e2e | grep -v system ) COMMIT_NO ?= $(shell git rev-parse HEAD 2> /dev/null || true) -GIT_COMMIT ?= $(if $(shell git status --porcelain --untracked-files=no),"${COMMIT_NO}-dirty","${COMMIT_NO}") +GIT_COMMIT ?= $(if $(shell git status --porcelain --untracked-files=no),${COMMIT_NO}-dirty,${COMMIT_NO}) BUILD_INFO ?= $(shell date +%s) LIBPOD := ${PROJECT}/libpod LDFLAGS_PODMAN ?= $(LDFLAGS) -X $(LIBPOD).gitCommit=$(GIT_COMMIT) -X $(LIBPOD).buildInfo=$(BUILD_INFO) @@ -94,6 +94,7 @@ help: ifeq ("$(wildcard $(GOPKGDIR))","") mkdir -p "$(GOPKGBASEDIR)" ln -sf "$(CURDIR)" "$(GOPKGBASEDIR)" + ln -sf "$(CURDIR)/vendor/github.com/varlink" "$(FIRST_GOPATH)/src/github.com/varlink" endif touch $@ diff --git a/cmd/podman/commands.go b/cmd/podman/commands.go index 2c56d5dec..90e2ab5cf 100644 --- a/cmd/podman/commands.go +++ b/cmd/podman/commands.go @@ -27,7 +27,6 @@ func getMainCommands() []*cobra.Command { _mountCommand, _pauseCommand, _portCommand, - _pushCommand, _refreshCommand, _restartCommand, _restoreCommand, @@ -42,10 +41,13 @@ func getMainCommands() []*cobra.Command { _topCommand, _umountCommand, _unpauseCommand, - _varlinkCommand, volumeCommand.Command, _waitCommand, } + + if len(_varlinkCommand.Use) > 0 { + rootCommands = append(rootCommands, _varlinkCommand) + } return rootCommands } @@ -54,7 +56,6 @@ func getImageSubCommands() []*cobra.Command { return []*cobra.Command{ _buildCommand, _loadCommand, - _pushCommand, _saveCommand, _signCommand, } diff --git a/cmd/podman/commands_remoteclient.go b/cmd/podman/commands_remoteclient.go index a656d5a29..7bdba1c19 100644 --- a/cmd/podman/commands_remoteclient.go +++ b/cmd/podman/commands_remoteclient.go @@ -36,6 +36,8 @@ func getVolumeSubCommands() []*cobra.Command { return []*cobra.Command{ _volumeCreateCommand, _volumeRmCommand, + _volumeLsCommand, + _volumeInspectCommand, } } diff --git a/cmd/podman/image.go b/cmd/podman/image.go index 74e28eeca..edc37b28a 100644 --- a/cmd/podman/image.go +++ b/cmd/podman/image.go @@ -25,6 +25,7 @@ var imageSubCommands = []*cobra.Command{ _inspectCommand, _pruneImagesCommand, _pullCommand, + _pushCommand, _rmiCommand, _tagCommand, } diff --git a/cmd/podman/images.go b/cmd/podman/images.go index a9e8abbde..b269f6440 100644 --- a/cmd/podman/images.go +++ b/cmd/podman/images.go @@ -247,8 +247,12 @@ func getImagesTemplateOutput(ctx context.Context, images []*adapter.ContainerIma } // get all specified repo:tag pairs and print them separately + repopairs, err := image.ReposToMap(img.Names()) + if err != nil { + logrus.Errorf("error finding tag/digest for %s", img.ID()) + } outer: - for repo, tags := range image.ReposToMap(img.Names()) { + for repo, tags := range repopairs { for _, tag := range tags { size, err := img.Size(ctx) var sizeStr string diff --git a/cmd/podman/main.go b/cmd/podman/main.go index 3facc146c..a6f0c500a 100644 --- a/cmd/podman/main.go +++ b/cmd/podman/main.go @@ -38,6 +38,7 @@ var mainCommands = []*cobra.Command{ _inspectCommand, _killCommand, _pullCommand, + _pushCommand, _rmiCommand, _tagCommand, _versionCommand, diff --git a/cmd/podman/port.go b/cmd/podman/port.go index 5a5b6127b..be84da065 100644 --- a/cmd/podman/port.go +++ b/cmd/podman/port.go @@ -125,8 +125,13 @@ func portCmd(c *cliconfig.PortValues) error { if c.All { fmt.Println(con.ID()) } + + portmappings, err := con.PortMappings() + if err != nil { + return err + } // Iterate mappings - for _, v := range con.Config().PortMappings { + for _, v := range portmappings { hostIP := v.HostIP // Set host IP to 0.0.0.0 if blank if hostIP == "" { diff --git a/cmd/podman/push.go b/cmd/podman/push.go index 017e4fbd2..bbe8a4027 100644 --- a/cmd/podman/push.go +++ b/cmd/podman/push.go @@ -2,8 +2,6 @@ package main import ( "fmt" - "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/spf13/cobra" "io" "os" "strings" @@ -11,11 +9,13 @@ import ( "github.com/containers/image/directory" "github.com/containers/image/manifest" "github.com/containers/image/types" - "github.com/containers/libpod/cmd/podman/libpodruntime" + "github.com/containers/libpod/cmd/podman/cliconfig" + "github.com/containers/libpod/libpod/adapter" "github.com/containers/libpod/libpod/image" "github.com/containers/libpod/pkg/util" imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" + "github.com/spf13/cobra" ) var ( @@ -93,7 +93,7 @@ func pushCmd(c *cliconfig.PushValues) error { registryCreds = creds } - runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand) + runtime, err := adapter.GetRuntime(&c.PodmanCommand) if err != nil { return errors.Wrapf(err, "could not create runtime") } @@ -131,12 +131,7 @@ func pushCmd(c *cliconfig.PushValues) error { SignBy: signBy, } - newImage, err := runtime.ImageRuntime().NewFromLocal(srcName) - if err != nil { - return err - } - authfile := getAuthFile(c.Authfile) - return newImage.PushImageToHeuristicDestination(getContext(), destName, manifestType, authfile, c.SignaturePolicy, writer, c.Compress, so, &dockerRegistryOptions, nil) + return runtime.Push(getContext(), srcName, destName, manifestType, authfile, c.SignaturePolicy, writer, c.Compress, so, &dockerRegistryOptions, nil) } diff --git a/cmd/podman/shared/container.go b/cmd/podman/shared/container.go index c74d8fdce..81811e0f2 100644 --- a/cmd/podman/shared/container.go +++ b/cmd/podman/shared/container.go @@ -213,11 +213,16 @@ func NewBatchContainer(ctr *libpod.Container, opts PsOptions) (PsContainerOutput } } + ports, err := ctr.PortMappings() + if err != nil { + logrus.Errorf("unable to lookup namespace container for %s", ctr.ID()) + } + pso.ID = cid pso.Image = imageName pso.Command = command pso.Created = created - pso.Ports = portsToString(ctr.PortMappings()) + pso.Ports = portsToString(ports) pso.Names = ctr.Name() pso.IsInfra = ctr.IsInfra() pso.Status = status diff --git a/cmd/podman/varlink.go b/cmd/podman/varlink.go index a49aae55b..ce54cfa85 100644 --- a/cmd/podman/varlink.go +++ b/cmd/podman/varlink.go @@ -83,7 +83,7 @@ func varlinkCmd(c *cliconfig.VarlinkValues) error { logrus.Infof("varlink service expired (use --timeout to increase session time beyond %d ms, 0 means never timeout)", c.Int64("timeout")) return nil default: - return errors.Errorf("unable to start varlink service") + return errors.Wrapf(err, "unable to start varlink service") } } diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink index b03fde0df..03ea06dfc 100644 --- a/cmd/podman/varlink/io.podman.varlink +++ b/cmd/podman/varlink/io.podman.varlink @@ -2,15 +2,13 @@ # in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in the upstream libpod repository. interface io.podman - -# Version is the structure returned by GetVersion -type Version ( - version: string, - go_version: string, - git_commit: string, - built: int, - os_arch: string, - remote_api_version: int +type Volume ( + name: string, + labels: [string]string, + mountPoint: string, + driver: string, + options: [string]string, + scope: string ) type NotImplemented ( @@ -20,6 +18,7 @@ type NotImplemented ( type StringResponse ( message: string ) + # ContainerChanges describes the return struct for ListContainerChanges type ContainerChanges ( changed: []string, @@ -40,14 +39,12 @@ type VolumeRemoveOpts ( force: bool ) -# ImageInList describes the structure that is returned in -# ListImages. -type ImageInList ( +type Image ( id: string, parentId: string, repoTags: []string, repoDigests: []string, - created: string, + created: string, # as RFC3339 size: int, virtualSize: int, containers: int, @@ -58,16 +55,15 @@ type ImageInList ( # ImageHistory describes the returned structure from ImageHistory. type ImageHistory ( id: string, - created: string, + created: string, # as RFC3339 createdBy: string, tags: []string, size: int, comment: string ) -# ImageSearch is the returned structure for SearchImage. It is returned -# in array form. -type ImageSearch ( +# Represents a single search result from SearchImages +type ImageSearchResult ( description: string, is_official: bool, is_automated: bool, @@ -75,13 +71,12 @@ type ImageSearch ( star_count: int ) -# ListContainerData is the returned struct for an individual container -type ListContainerData ( +type Container ( id: string, image: string, imageid: string, command: []string, - createdat: string, + createdat: string, # as RFC3339 runningfor: string, status: string, ports: []ContainerPortMappings, @@ -345,8 +340,8 @@ type BuildInfo ( image_format: string ) -# BuildResponse is used to describe the responses for building images -type BuildResponse ( +# MoreResponse is a struct for when responses from varlink requires longer output +type MoreResponse ( logs: []string, id: string ) @@ -406,34 +401,29 @@ type Runlabel( opts: [string]string ) -# Ping provides a response for developers to ensure their varlink setup is working. -# #### Example -# ~~~ -# $ varlink call -m unix:/run/podman/io.podman/io.podman.Ping -# { -# "ping": { -# "message": "OK" -# } -# } -# ~~~ -method Ping() -> (ping: StringResponse) - -# GetVersion returns a Version structure describing the libpod setup on their -# system. -method GetVersion() -> (version: Version) +# GetVersion returns version and build information of the podman service +method GetVersion() -> ( + version: string, + go_version: string, + git_commit: string, + built: string, # as RFC3339 + os_arch: string, + remote_api_version: int +) # GetInfo returns a [PodmanInfo](#PodmanInfo) struct that describes podman and its host such as storage stats, # build information of Podman, and system-wide registries. method GetInfo() -> (info: PodmanInfo) -# ListContainers returns a list of containers in no particular order. There are -# returned as an array of ListContainerData structs. See also [GetContainer](#GetContainer). -method ListContainers() -> (containers: []ListContainerData) +# ListContainers returns information about all containers. +# See also [GetContainer](#GetContainer). +method ListContainers() -> (containers: []Container) -# GetContainer takes a name or ID of a container and returns single ListContainerData -# structure. A [ContainerNotFound](#ContainerNotFound) error will be returned if the container cannot be found. -# See also [ListContainers](ListContainers) and [InspectContainer](#InspectContainer). -method GetContainer(name: string) -> (container: ListContainerData) +# GetContainer returns information about a single container. If a container +# with the given id doesn't exist, a [ContainerNotFound](#ContainerNotFound) +# error will be returned. See also [ListContainers](ListContainers) and +# [InspectContainer](#InspectContainer). +method GetContainer(id: string) -> (container: Container) # CreateContainer creates a new container from an image. It uses a [Create](#Create) type for input. The minimum # input required for CreateContainer is an image name. If the image name is not found, an [ImageNotFound](#ImageNotFound) @@ -521,7 +511,7 @@ method ExportContainer(name: string, path: string) -> (tarfile: string) method GetContainerStats(name: string) -> (container: ContainerStats) # This method has not be implemented yet. -method ResizeContainerTty() -> (notimplemented: NotImplemented) +# method ResizeContainerTty() -> (notimplemented: NotImplemented) # StartContainer starts a created or stopped container. It takes the name or ID of container. It returns # the container ID once started. If the container cannot be found, a [ContainerNotFound](#ContainerNotFound) @@ -553,10 +543,10 @@ method RestartContainer(name: string, timeout: int) -> (container: string) method KillContainer(name: string, signal: int) -> (container: string) # This method has not be implemented yet. -method UpdateContainer() -> (notimplemented: NotImplemented) +# method UpdateContainer() -> (notimplemented: NotImplemented) # This method has not be implemented yet. -method RenameContainer() -> (notimplemented: NotImplemented) +# method RenameContainer() -> (notimplemented: NotImplemented) # PauseContainer takes the name or ID of container and pauses it. If the container cannot be found, # a [ContainerNotFound](#ContainerNotFound) error will be returned; otherwise the ID of the container is returned. @@ -569,7 +559,7 @@ method PauseContainer(name: string) -> (container: string) method UnpauseContainer(name: string) -> (container: string) # This method has not be implemented yet. -method AttachToContainer() -> (notimplemented: NotImplemented) +# method AttachToContainer() -> (notimplemented: NotImplemented) # GetAttachSockets takes the name or ID of an existing container. It returns file paths for two sockets needed # to properly communicate with a container. The first is the actual I/O socket that the container uses. The @@ -621,21 +611,21 @@ method RemoveContainer(name: string, force: bool) -> (container: string) # ~~~ method DeleteStoppedContainers() -> (containers: []string) -# ListImages returns an array of ImageInList structures which provide basic information about -# an image currently in storage. See also [InspectImage](InspectImage). -method ListImages() -> (images: []ImageInList) +# ListImages returns information about the images that are currently in storage. +# See also [InspectImage](InspectImage). +method ListImages() -> (images: []Image) -# GetImage returns a single image in an [ImageInList](#ImageInList) struct. You must supply an image name as a string. -# If the image cannot be found, an [ImageNotFound](#ImageNotFound) error will be returned. -method GetImage(name: string) -> (image: ImageInList) +# GetImage returns information about a single image in storage. +# If the image caGetImage returns be found, [ImageNotFound](#ImageNotFound) will be returned. +method GetImage(id: string) -> (image: Image) # 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 [BuildResponse](#BuildResponse) 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. -method BuildImage(build: BuildInfo) -> (image: BuildResponse) +method BuildImage(build: BuildInfo) -> (image: MoreResponse) # This function is not implemented yet. -method CreateImage() -> (notimplemented: NotImplemented) +# method CreateImage() -> (notimplemented: NotImplemented) # InspectImage takes the name or ID of an image and returns a string respresentation of data associated with the #image. You must serialize the string into JSON to use it further. An [ImageNotFound](#ImageNotFound) error will @@ -650,8 +640,8 @@ method HistoryImage(name: string) -> (history: []ImageHistory) # PushImage takes three input arguments: the name or ID of an image, the fully-qualified destination name of the image, # and a boolean as to whether tls-verify should be used (with false disabling TLS, not affecting the default behavior). # It will return an [ImageNotFound](#ImageNotFound) error if -# the image cannot be found in local storage; otherwise the ID of the image will be returned on success. -method PushImage(name: string, tag: string, tlsverify: bool, signaturePolicy: string, creds: string, certDir: string, compress: bool, format: string, removeSignatures: bool, signBy: string) -> (image: string) +# the image cannot be found in local storage; otherwise it will return a [MoreResponse](#MoreResponse) +method PushImage(name: string, tag: string, tlsverify: bool, signaturePolicy: string, creds: string, certDir: string, compress: bool, format: string, removeSignatures: bool, signBy: string) -> (reply: MoreResponse) # TagImage takes the name or ID of an image in local storage as well as the desired tag name. If the image cannot # be found, an [ImageNotFound](#ImageNotFound) error will be returned; otherwise, the ID of the image is returned on success. @@ -669,10 +659,10 @@ method TagImage(name: string, tagged: string) -> (image: string) # ~~~ method RemoveImage(name: string, force: bool) -> (image: string) -# SearchImage takes the string of an image name and a limit of searches from each registries to be returned. SearchImage -# will then use a glob-like match to find the image you are searching for. The images are returned in an array of -# ImageSearch structures which contain information about the image as well as its fully-qualified name. -method SearchImage(name: string, limit: int) -> (images: []ImageSearch) +# SearchImages searches available registries for images that contain the +# contents of "query" in their name. If "limit" is given, limits the amount of +# search results per registry. +method SearchImages(query: string, limit: ?int) -> (results: []ImageSearchResult) # DeleteUnusedImages deletes any images not associated with a container. The IDs of the deleted images are returned # in a string array. @@ -926,10 +916,10 @@ method UnpausePod(name: string) -> (pod: string) method RemovePod(name: string, force: bool) -> (pod: string) # This method has not be implemented yet. -method WaitPod() -> (notimplemented: NotImplemented) +# method WaitPod() -> (notimplemented: NotImplemented) # This method has not been implemented yet. -method TopPod() -> (notimplemented: NotImplemented) +# method TopPod() -> (notimplemented: NotImplemented) # GetPodStats takes the name or ID of a pod and returns a pod name and slice of ContainerStats structure which # contains attributes like memory and cpu usage. If the pod cannot be found, a [PodNotFound](#PodNotFound) @@ -1033,19 +1023,19 @@ method UnmountContainer(name: string, force: bool) -> () method ImagesPrune(all: bool) -> (pruned: []string) # This function is not implemented yet. -method ListContainerPorts(name: string) -> (notimplemented: NotImplemented) +# method ListContainerPorts(name: string) -> (notimplemented: NotImplemented) # GenerateKube generates a Kubernetes v1 Pod description of a Podman container or pod # and its containers. The description is in YAML. See also [ReplayKube](ReplayKube). -method GenerateKube() -> (notimplemented: NotImplemented) +# method GenerateKube() -> (notimplemented: NotImplemented) # GenerateKubeService generates a Kubernetes v1 Service description of a Podman container or pod # and its containers. The description is in YAML. See also [GenerateKube](GenerateKube). -method GenerateKubeService() -> (notimplemented: NotImplemented) +# method GenerateKubeService() -> (notimplemented: NotImplemented) # ReplayKube recreates a pod and its containers based on a Kubernetes v1 Pod description (in YAML) # like that created by GenerateKube. See also [GenerateKube](GenerateKube). -method ReplayKube() -> (notimplemented: NotImplemented) +# method ReplayKube() -> (notimplemented: NotImplemented) # ContainerConfig returns a container's config in string form. This call is for # development of Podman only and generally should not be used. @@ -1070,12 +1060,13 @@ method VolumeCreate(options: VolumeCreateOpts) -> (volumeName: string) method VolumeRemove(options: VolumeRemoveOpts) -> (volumeNames: []string) +method GetVolumes(args: []string, all: bool) -> (volumes: []Volume) # ImageNotFound means the image could not be found by the provided name or ID in local storage. -error ImageNotFound (name: string) +error ImageNotFound (id: string) # ContainerNotFound means the container could not be found by the provided name or ID in local storage. -error ContainerNotFound (name: string) +error ContainerNotFound (id: string) # NoContainerRunning means none of the containers requested are running in a command that requires a running container. error NoContainerRunning () diff --git a/cmd/podman/varlink_dummy.go b/cmd/podman/varlink_dummy.go index 8d7a7e8ca..430511d72 100644 --- a/cmd/podman/varlink_dummy.go +++ b/cmd/podman/varlink_dummy.go @@ -2,8 +2,10 @@ package main -import ( - "github.com/containers/libpod/cmd/podman/cliconfig" -) +import "github.com/spf13/cobra" -var varlinkCommand *cliconfig.PodmanCommand +var ( + _varlinkCommand = &cobra.Command{ + Use: "", + } +) diff --git a/cmd/podman/volume_inspect.go b/cmd/podman/volume_inspect.go index a8e6f489f..928ef37d0 100644 --- a/cmd/podman/volume_inspect.go +++ b/cmd/podman/volume_inspect.go @@ -2,9 +2,8 @@ package main import ( "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/cmd/podman/libpodruntime" + "github.com/containers/libpod/libpod/adapter" "github.com/pkg/errors" - "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -39,22 +38,19 @@ func init() { } func volumeInspectCmd(c *cliconfig.VolumeInspectValues) error { - var err error + if (c.All && len(c.InputArgs) > 0) || (!c.All && len(c.InputArgs) < 1) { + return errors.New("provide one or more volume names or use --all") + } - runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand) + runtime, err := adapter.GetRuntime(&c.PodmanCommand) if err != nil { return errors.Wrapf(err, "error creating libpod runtime") } defer runtime.Shutdown(false) - opts := volumeLsOptions{ - Format: c.Format, - } - - vols, lastError := getVolumesFromContext(&c.PodmanCommand, runtime) - if lastError != nil { - logrus.Errorf("%q", lastError) + vols, err := runtime.InspectVolumes(getContext(), c) + if err != nil { + return err } - - return generateVolLsOutput(vols, opts, runtime) + return generateVolLsOutput(vols, volumeLsOptions{Format: c.Format}) } diff --git a/cmd/podman/volume_ls.go b/cmd/podman/volume_ls.go index 87b14a4b2..0edadc5ac 100644 --- a/cmd/podman/volume_ls.go +++ b/cmd/podman/volume_ls.go @@ -6,8 +6,7 @@ import ( "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/cmd/podman/formats" - "github.com/containers/libpod/cmd/podman/libpodruntime" - "github.com/containers/libpod/libpod" + "github.com/containers/libpod/libpod/adapter" "github.com/pkg/errors" "github.com/spf13/cobra" ) @@ -71,7 +70,7 @@ func init() { } func volumeLsCmd(c *cliconfig.VolumeLsValues) error { - runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand) + runtime, err := adapter.GetRuntime(&c.PodmanCommand) if err != nil { return errors.Wrapf(err, "error creating libpod runtime") } @@ -87,7 +86,7 @@ func volumeLsCmd(c *cliconfig.VolumeLsValues) error { opts.Format = genVolLsFormat(c) // Get the filter functions based on any filters set - var filterFuncs []libpod.VolumeFilter + var filterFuncs []adapter.VolumeFilter if c.Filter != "" { filters := strings.Split(c.Filter, ",") for _, f := range filters { @@ -95,7 +94,7 @@ func volumeLsCmd(c *cliconfig.VolumeLsValues) error { if len(filterSplit) < 2 { return errors.Errorf("filter input must be in the form of filter=value: %s is invalid", f) } - generatedFunc, err := generateVolumeFilterFuncs(filterSplit[0], filterSplit[1], runtime) + generatedFunc, err := generateVolumeFilterFuncs(filterSplit[0], filterSplit[1]) if err != nil { return errors.Wrapf(err, "invalid filter") } @@ -103,13 +102,12 @@ func volumeLsCmd(c *cliconfig.VolumeLsValues) error { } } - volumes, err := runtime.GetAllVolumes() + volumes, err := runtime.Volumes(getContext()) if err != nil { return err } - // Get the volumes that match the filter - volsFiltered := make([]*libpod.Volume, 0, len(volumes)) + volsFiltered := make([]*adapter.Volume, 0, len(volumes)) for _, vol := range volumes { include := true for _, filter := range filterFuncs { @@ -120,7 +118,7 @@ func volumeLsCmd(c *cliconfig.VolumeLsValues) error { volsFiltered = append(volsFiltered, vol) } } - return generateVolLsOutput(volsFiltered, opts, runtime) + return generateVolLsOutput(volsFiltered, opts) } // generate the template based on conditions given @@ -206,7 +204,7 @@ func getVolTemplateOutput(lsParams []volumeLsJSONParams, opts volumeLsOptions) ( } // getVolJSONParams returns the volumes in JSON format -func getVolJSONParams(volumes []*libpod.Volume, opts volumeLsOptions, runtime *libpod.Runtime) ([]volumeLsJSONParams, error) { +func getVolJSONParams(volumes []*adapter.Volume) []volumeLsJSONParams { var lsOutput []volumeLsJSONParams for _, volume := range volumes { @@ -221,25 +219,19 @@ func getVolJSONParams(volumes []*libpod.Volume, opts volumeLsOptions, runtime *l lsOutput = append(lsOutput, params) } - return lsOutput, nil + return lsOutput } // generateVolLsOutput generates the output based on the format, JSON or Go Template, and prints it out -func generateVolLsOutput(volumes []*libpod.Volume, opts volumeLsOptions, runtime *libpod.Runtime) error { +func generateVolLsOutput(volumes []*adapter.Volume, opts volumeLsOptions) error { if len(volumes) == 0 && opts.Format != formats.JSONString { return nil } - lsOutput, err := getVolJSONParams(volumes, opts, runtime) - if err != nil { - return err - } + lsOutput := getVolJSONParams(volumes) var out formats.Writer switch opts.Format { case formats.JSONString: - if err != nil { - return errors.Wrapf(err, "unable to create JSON for volume output") - } out = formats.JSONStructArray{Output: volLsToGeneric([]volumeLsTemplateParams{}, lsOutput)} default: lsOutput, err := getVolTemplateOutput(lsOutput, opts) @@ -252,18 +244,18 @@ func generateVolLsOutput(volumes []*libpod.Volume, opts volumeLsOptions, runtime } // generateVolumeFilterFuncs returns the true if the volume matches the filter set, otherwise it returns false. -func generateVolumeFilterFuncs(filter, filterValue string, runtime *libpod.Runtime) (func(volume *libpod.Volume) bool, error) { +func generateVolumeFilterFuncs(filter, filterValue string) (func(volume *adapter.Volume) bool, error) { switch filter { case "name": - return func(v *libpod.Volume) bool { + return func(v *adapter.Volume) bool { return strings.Contains(v.Name(), filterValue) }, nil case "driver": - return func(v *libpod.Volume) bool { + return func(v *adapter.Volume) bool { return v.Driver() == filterValue }, nil case "scope": - return func(v *libpod.Volume) bool { + return func(v *adapter.Volume) bool { return v.Scope() == filterValue }, nil case "label": @@ -274,7 +266,7 @@ func generateVolumeFilterFuncs(filter, filterValue string, runtime *libpod.Runti } else { filterValue = "" } - return func(v *libpod.Volume) bool { + return func(v *adapter.Volume) bool { for labelKey, labelValue := range v.Labels() { if labelKey == filterKey && ("" == filterValue || labelValue == filterValue) { return true @@ -290,7 +282,7 @@ func generateVolumeFilterFuncs(filter, filterValue string, runtime *libpod.Runti } else { filterValue = "" } - return func(v *libpod.Volume) bool { + return func(v *adapter.Volume) bool { for labelKey, labelValue := range v.Options() { if labelKey == filterKey && ("" == filterValue || labelValue == filterValue) { return true diff --git a/completions/bash/podman b/completions/bash/podman index 9df87aef4..d367b8237 100644 --- a/completions/bash/podman +++ b/completions/bash/podman @@ -1691,6 +1691,7 @@ _podman_container_run() { --oom-score-adj --pid --pids-limit + --pod --publish -p --runtime --rootfs diff --git a/hack/get_ci_vm.sh b/hack/get_ci_vm.sh index b058b4273..3c2d193af 100755 --- a/hack/get_ci_vm.sh +++ b/hack/get_ci_vm.sh @@ -17,8 +17,14 @@ MEMORY="4Gb" DISK="200" PROJECT="libpod-218412" GOSRC="/var/tmp/go/src/github.com/containers/libpod" +GCLOUD_IMAGE=${GCLOUD_IMAGE:-quay.io/cevich/gcloud_centos:latest} +GCLOUD_SUDO=${GCLOUD_SUDO-sudo} + +# Shared tmp directory between container and us +TMPDIR=$(mktemp -d --tmpdir $(basename $0)_tmpdir_XXXXXX) + # Command shortcuts save some typing -PGCLOUD="sudo podman run -it --rm -e AS_ID=$UID -e AS_USER=$USER --security-opt label=disable -v /home/$USER:$HOME -v /tmp:/tmp:ro quay.io/cevich/gcloud_centos:latest --configuration=libpod --project=$PROJECT" +PGCLOUD="$GCLOUD_SUDO podman run -it --rm -e AS_ID=$UID -e AS_USER=$USER --security-opt label=disable -v /home/$USER:$HOME -v $TMPDIR:/tmp $GCLOUD_IMAGE --configuration=libpod --project=$PROJECT" SCP_CMD="$PGCLOUD compute scp" LIBPODROOT=$(realpath "$(dirname $0)/../") @@ -39,19 +45,20 @@ showrun() { fi } -TEMPFILE=$(mktemp -p '' $(basename $0)_XXXXX.tar.bz2) cleanup() { set +e wait - rm -f "$TEMPFILE" + + # set GCLOUD_DEBUG to leave tmpdir behind for postmortem + test -z "$GCLOUD_DEBUG" && rm -rf $TMPDIR } trap cleanup EXIT delvm() { - cleanup echo -e "\n" echo -e "\n${YEL}Offering to Delete $VMNAME ${RED}(Might take a minute or two)${NOR}" showrun $CLEANUP_CMD # prompts for Yes/No + cleanup } image_hints() { @@ -128,16 +135,16 @@ parse_args $@ cd $LIBPODROOT # Attempt to determine if named 'libpod' gcloud configuration exists -showrun $PGCLOUD info > $TEMPFILE -if egrep -q "Account:.*None" "$TEMPFILE" +showrun $PGCLOUD info > $TMPDIR/gcloud-info +if egrep -q "Account:.*None" $TMPDIR/gcloud-info then echo -e "\n${YEL}WARNING: Can't find gcloud configuration for libpod, running init.${NOR}" echo -e " ${RED}Please choose "#1: Re-initialize" and "login" if asked.${NOR}" showrun $PGCLOUD init --project=$PROJECT --console-only --skip-diagnostics # Verify it worked (account name == someone@example.com) - $PGCLOUD info > $TEMPFILE - if egrep -q "Account:.*None" "$TEMPFILE" + $PGCLOUD info > $TMPDIR/gcloud-info-after-init + if egrep -q "Account:.*None" $TMPDIR/gcloud-info-after-init then echo -e "${RED}ERROR: Could not initialize libpod configuration in gcloud.${NOR}" exit 5 @@ -150,8 +157,10 @@ then fi # Couldn't make rsync work with gcloud's ssh wrapper :( +TARBALL_BASENAME=$VMNAME.tar.bz2 +TARBALL=/tmp/$TARBALL_BASENAME echo -e "\n${YEL}Packing up repository into a tarball $VMNAME.${NOR}" -showrun --background tar cjf $TEMPFILE --warning=no-file-changed -C $LIBPODROOT . +showrun --background tar cjf $TMPDIR/$TARBALL_BASENAME --warning=no-file-changed -C $LIBPODROOT . trap delvm INT # Allow deleting VM if CTRL-C during create # This fails if VM already exists: permit this usage to re-init @@ -186,13 +195,13 @@ showrun $SSH_CMD --command "mkdir -p $GOSRC" echo -e "\n${YEL}Transfering tarball to $VMNAME.${NOR}" wait -showrun $SCP_CMD $TEMPFILE root@$VMNAME:$TEMPFILE +showrun $SCP_CMD $TARBALL root@$VMNAME:$TARBALL echo -e "\n${YEL}Unpacking tarball into $GOSRC on $VMNAME.${NOR}" -showrun $SSH_CMD --command "tar xjf $TEMPFILE -C $GOSRC" +showrun $SSH_CMD --command "tar xjf $TARBALL -C $GOSRC" echo -e "\n${YEL}Removing tarball on $VMNAME.${NOR}" -showrun $SSH_CMD --command "rm -f $TEMPFILE" +showrun $SSH_CMD --command "rm -f $TARBALL" echo -e "\n${YEL}Executing environment setup${NOR}" [[ "$1" == "-p" ]] && echo -e "${RED}Using package-based dependencies.${NOR}" diff --git a/libpod/adapter/runtime.go b/libpod/adapter/runtime.go index 2b1ddb09d..7dd845616 100644 --- a/libpod/adapter/runtime.go +++ b/libpod/adapter/runtime.go @@ -4,18 +4,19 @@ package adapter import ( "context" - "github.com/pkg/errors" "io" "io/ioutil" "os" "strconv" + "github.com/containers/image/docker/reference" "github.com/containers/image/types" "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/cmd/podman/libpodruntime" "github.com/containers/libpod/libpod" "github.com/containers/libpod/libpod/image" "github.com/containers/libpod/pkg/rootless" + "github.com/pkg/errors" ) // LocalRuntime describes a typical libpod runtime @@ -34,6 +35,14 @@ type Container struct { *libpod.Container } +// Volume ... +type Volume struct { + *libpod.Volume +} + +// VolumeFilter is for filtering volumes on the client +type VolumeFilter func(*Volume) bool + // GetRuntime returns a LocalRuntime struct with the actual runtime embedded in it func GetRuntime(c *cliconfig.PodmanCommand) (*LocalRuntime, error) { runtime, err := libpodruntime.GetRuntime(c) @@ -190,3 +199,58 @@ func (r *LocalRuntime) CreateVolume(ctx context.Context, c *cliconfig.VolumeCrea func (r *LocalRuntime) RemoveVolumes(ctx context.Context, c *cliconfig.VolumeRmValues) ([]string, error) { return r.Runtime.RemoveVolumes(ctx, c.InputArgs, c.All, c.Force) } + +// Push is a wrapper to push an image to a registry +func (r *LocalRuntime) Push(ctx context.Context, srcName, destination, manifestMIMEType, authfile, signaturePolicyPath string, writer io.Writer, forceCompress bool, signingOptions image.SigningOptions, dockerRegistryOptions *image.DockerRegistryOptions, additionalDockerArchiveTags []reference.NamedTagged) error { + newImage, err := r.ImageRuntime().NewFromLocal(srcName) + if err != nil { + return err + } + return newImage.PushImageToHeuristicDestination(ctx, destination, manifestMIMEType, authfile, signaturePolicyPath, writer, forceCompress, signingOptions, dockerRegistryOptions, nil) +} + +// InspectVolumes returns a slice of volumes based on an arg list or --all +func (r *LocalRuntime) InspectVolumes(ctx context.Context, c *cliconfig.VolumeInspectValues) ([]*Volume, error) { + var ( + volumes []*libpod.Volume + err error + ) + + if c.All { + volumes, err = r.GetAllVolumes() + } else { + for _, v := range c.InputArgs { + vol, err := r.GetVolume(v) + if err != nil { + return nil, err + } + volumes = append(volumes, vol) + } + } + if err != nil { + return nil, err + } + return libpodVolumeToVolume(volumes), nil +} + +// Volumes returns a slice of localruntime volumes +func (r *LocalRuntime) Volumes(ctx context.Context) ([]*Volume, error) { + vols, err := r.GetAllVolumes() + if err != nil { + return nil, err + } + return libpodVolumeToVolume(vols), nil +} + +// libpodVolumeToVolume converts a slice of libpod volumes to a slice +// of localruntime volumes (same as libpod) +func libpodVolumeToVolume(volumes []*libpod.Volume) []*Volume { + var vols []*Volume + for _, v := range volumes { + newVol := Volume{ + v, + } + vols = append(vols, &newVol) + } + return vols +} diff --git a/libpod/adapter/runtime_remote.go b/libpod/adapter/runtime_remote.go index 4dfae34e1..d0d827582 100644 --- a/libpod/adapter/runtime_remote.go +++ b/libpod/adapter/runtime_remote.go @@ -13,6 +13,7 @@ import ( "strings" "time" + "github.com/containers/image/docker/reference" "github.com/containers/image/types" "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/cmd/podman/varlink" @@ -91,6 +92,18 @@ type remoteContainer struct { state *libpod.ContainerState } +type VolumeFilter func(*Volume) bool + +// Volume is embed for libpod volumes +type Volume struct { + remoteVolume +} + +type remoteVolume struct { + Runtime *LocalRuntime + config *libpod.VolumeConfig +} + // GetImages returns a slice of containerimages over a varlink connection func (r *LocalRuntime) GetImages() ([]*ContainerImage, error) { var newImages []*ContainerImage @@ -112,8 +125,8 @@ func (r *LocalRuntime) GetImages() ([]*ContainerImage, error) { return newImages, nil } -func imageInListToContainerImage(i iopodman.ImageInList, name string, runtime *LocalRuntime) (*ContainerImage, error) { - created, err := splitStringDate(i.Created) +func imageInListToContainerImage(i iopodman.Image, name string, runtime *LocalRuntime) (*ContainerImage, error) { + created, err := time.ParseInLocation(time.RFC3339, i.Created, time.UTC) if err != nil { return nil, err } @@ -182,12 +195,6 @@ func (r *LocalRuntime) New(ctx context.Context, name, signaturePolicyPath, authf return newImage, nil } -func splitStringDate(d string) (time.Time, error) { - fields := strings.Fields(d) - t := fmt.Sprintf("%sT%sZ", fields[0], fields[1]) - return time.ParseInLocation(time.RFC3339Nano, t, time.UTC) -} - // IsParent goes through the layers in the store and checks if i.TopLayer is // the parent of any other layer in store. Double check that image with that // layer exists as well. @@ -251,7 +258,7 @@ func (ci *ContainerImage) History(ctx context.Context) ([]*image.History, error) return nil, err } for _, h := range reply { - created, err := splitStringDate(h.Created) + created, err := time.ParseInLocation(time.RFC3339, h.Created, time.UTC) if err != nil { return nil, err } @@ -459,3 +466,71 @@ func (r *LocalRuntime) RemoveVolumes(ctx context.Context, c *cliconfig.VolumeRmV } return iopodman.VolumeRemove().Call(r.Conn, rmOpts) } + +func (r *LocalRuntime) Push(ctx context.Context, srcName, destination, manifestMIMEType, authfile, signaturePolicyPath string, writer io.Writer, forceCompress bool, signingOptions image.SigningOptions, dockerRegistryOptions *image.DockerRegistryOptions, additionalDockerArchiveTags []reference.NamedTagged) error { + + tls := true + if dockerRegistryOptions.DockerInsecureSkipTLSVerify == types.OptionalBoolTrue { + tls = false + } + reply, err := iopodman.PushImage().Send(r.Conn, varlink.More, srcName, destination, tls, signaturePolicyPath, "", dockerRegistryOptions.DockerCertPath, forceCompress, manifestMIMEType, signingOptions.RemoveSignatures, signingOptions.SignBy) + if err != nil { + return err + } + for { + responses, flags, err := reply() + if err != nil { + return err + } + for _, line := range responses.Logs { + fmt.Print(line) + } + if flags&varlink.Continues == 0 { + break + } + } + + return err +} + +// InspectVolumes returns a slice of volumes based on an arg list or --all +func (r *LocalRuntime) InspectVolumes(ctx context.Context, c *cliconfig.VolumeInspectValues) ([]*Volume, error) { + reply, err := iopodman.GetVolumes().Call(r.Conn, c.InputArgs, c.All) + if err != nil { + return nil, err + } + return varlinkVolumeToVolume(r, reply), nil +} + +//Volumes returns a slice of adapter.volumes based on information about libpod +// volumes over a varlink connection +func (r *LocalRuntime) Volumes(ctx context.Context) ([]*Volume, error) { + reply, err := iopodman.GetVolumes().Call(r.Conn, []string{}, true) + if err != nil { + return nil, err + } + return varlinkVolumeToVolume(r, reply), nil +} + +func varlinkVolumeToVolume(r *LocalRuntime, volumes []iopodman.Volume) []*Volume { + var vols []*Volume + for _, v := range volumes { + volumeConfig := libpod.VolumeConfig{ + Name: v.Name, + Labels: v.Labels, + MountPoint: v.MountPoint, + Driver: v.Driver, + Options: v.Options, + Scope: v.Scope, + } + n := remoteVolume{ + Runtime: r, + config: &volumeConfig, + } + newVol := Volume{ + n, + } + vols = append(vols, &newVol) + } + return vols +} diff --git a/libpod/adapter/volumes_remote.go b/libpod/adapter/volumes_remote.go new file mode 100644 index 000000000..beacd943a --- /dev/null +++ b/libpod/adapter/volumes_remote.go @@ -0,0 +1,33 @@ +// +build remoteclient + +package adapter + +// Name returns the name of the volume +func (v *Volume) Name() string { + return v.config.Name +} + +//Labels returns the labels for a volume +func (v *Volume) Labels() map[string]string { + return v.config.Labels +} + +// Driver returns the driver for the volume +func (v *Volume) Driver() string { + return v.config.Driver +} + +// Options returns the options a volume was created with +func (v *Volume) Options() map[string]string { + return v.config.Options +} + +// MountPath returns the path the volume is mounted to +func (v *Volume) MountPoint() string { + return v.config.MountPoint +} + +// Scope returns the scope for an adapter.volume +func (v *Volume) Scope() string { + return v.config.Scope +} diff --git a/libpod/container.go b/libpod/container.go index b0589be3b..fec61533d 100644 --- a/libpod/container.go +++ b/libpod/container.go @@ -557,8 +557,16 @@ func (c *Container) NewNetNS() bool { // PortMappings returns the ports that will be mapped into a container if // a new network namespace is created // If NewNetNS() is false, this value is unused -func (c *Container) PortMappings() []ocicni.PortMapping { - return c.config.PortMappings +func (c *Container) PortMappings() ([]ocicni.PortMapping, error) { + // First check if the container belongs to a network namespace (like a pod) + if len(c.config.NetNsCtr) > 0 { + netNsCtr, err := c.runtime.LookupContainer(c.config.NetNsCtr) + if err != nil { + return nil, errors.Wrapf(err, "unable to lookup network namespace for container %s", c.ID()) + } + return netNsCtr.PortMappings() + } + return c.config.PortMappings, nil } // DNSServers returns DNS servers that will be used in the container's diff --git a/libpod/image/utils.go b/libpod/image/utils.go index ad027f32a..3585428ad 100644 --- a/libpod/image/utils.go +++ b/libpod/image/utils.go @@ -87,22 +87,29 @@ func hasTransport(image string) bool { // ReposToMap parses the specified repotags and returns a map with repositories // as keys and the corresponding arrays of tags as values. -func ReposToMap(repotags []string) map[string][]string { +func ReposToMap(repotags []string) (map[string][]string, error) { // map format is repo -> tag repos := make(map[string][]string) for _, repo := range repotags { var repository, tag string if len(repo) > 0 { - li := strings.LastIndex(repo, ":") - repository = repo[0:li] - tag = repo[li+1:] + named, err := reference.ParseNormalizedNamed(repo) + repository = named.Name() + if err != nil { + return nil, err + } + if ref, ok := named.(reference.NamedTagged); ok { + tag = ref.Tag() + } else if ref, ok := named.(reference.Canonical); ok { + tag = ref.Digest().String() + } } repos[repository] = append(repos[repository], tag) } if len(repos) == 0 { repos["<none>"] = []string{"<none>"} } - return repos + return repos, nil } // GetAdditionalTags returns a list of reference.NamedTagged for the diff --git a/libpod/kube.go b/libpod/kube.go index 16cebf99b..484127870 100644 --- a/libpod/kube.go +++ b/libpod/kube.go @@ -228,7 +228,11 @@ func containerToV1Container(c *Container) (v1.Container, error) { return kubeContainer, nil } - ports, err := ocicniPortMappingToContainerPort(c.PortMappings()) + portmappings, err := c.PortMappings() + if err != nil { + return kubeContainer, err + } + ports, err := ocicniPortMappingToContainerPort(portmappings) if err != nil { return kubeContainer, nil } diff --git a/pkg/varlinkapi/containers.go b/pkg/varlinkapi/containers.go index 737e2dd96..2b2832838 100644 --- a/pkg/varlinkapi/containers.go +++ b/pkg/varlinkapi/containers.go @@ -21,7 +21,7 @@ import ( // ListContainers ... func (i *LibpodAPI) ListContainers(call iopodman.VarlinkCall) error { var ( - listContainers []iopodman.ListContainerData + listContainers []iopodman.Container ) containers, err := i.Runtime.GetAllContainers() @@ -44,10 +44,10 @@ func (i *LibpodAPI) ListContainers(call iopodman.VarlinkCall) error { } // GetContainer ... -func (i *LibpodAPI) GetContainer(call iopodman.VarlinkCall, name string) error { - ctr, err := i.Runtime.LookupContainer(name) +func (i *LibpodAPI) GetContainer(call iopodman.VarlinkCall, id string) error { + ctr, err := i.Runtime.LookupContainer(id) if err != nil { - return call.ReplyContainerNotFound(name) + return call.ReplyContainerNotFound(id) } opts := shared.PsOptions{ Namespace: true, @@ -247,11 +247,6 @@ func (i *LibpodAPI) GetContainerStats(call iopodman.VarlinkCall, name string) er return call.ReplyGetContainerStats(cs) } -// ResizeContainerTty ... -func (i *LibpodAPI) ResizeContainerTty(call iopodman.VarlinkCall) error { - return call.ReplyMethodNotImplemented("ResizeContainerTty") -} - // StartContainer ... func (i *LibpodAPI) StartContainer(call iopodman.VarlinkCall, name string) error { ctr, err := i.Runtime.LookupContainer(name) @@ -324,16 +319,6 @@ func (i *LibpodAPI) KillContainer(call iopodman.VarlinkCall, name string, signal return call.ReplyKillContainer(ctr.ID()) } -// UpdateContainer ... -func (i *LibpodAPI) UpdateContainer(call iopodman.VarlinkCall) error { - return call.ReplyMethodNotImplemented("UpdateContainer") -} - -// RenameContainer ... -func (i *LibpodAPI) RenameContainer(call iopodman.VarlinkCall) error { - return call.ReplyMethodNotImplemented("RenameContainer") -} - // PauseContainer ... func (i *LibpodAPI) PauseContainer(call iopodman.VarlinkCall, name string) error { ctr, err := i.Runtime.LookupContainer(name) @@ -358,12 +343,6 @@ func (i *LibpodAPI) UnpauseContainer(call iopodman.VarlinkCall, name string) err return call.ReplyUnpauseContainer(ctr.ID()) } -// AttachToContainer ... -// TODO: DO we also want a different one for websocket? -func (i *LibpodAPI) AttachToContainer(call iopodman.VarlinkCall) error { - return call.ReplyMethodNotImplemented("AttachToContainer") -} - // WaitContainer ... func (i *LibpodAPI) WaitContainer(call iopodman.VarlinkCall, name string) error { ctr, err := i.Runtime.LookupContainer(name) diff --git a/pkg/varlinkapi/images.go b/pkg/varlinkapi/images.go index 5e0889645..ca920dfeb 100644 --- a/pkg/varlinkapi/images.go +++ b/pkg/varlinkapi/images.go @@ -28,6 +28,7 @@ import ( "github.com/opencontainers/image-spec/specs-go/v1" "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" + "github.com/sirupsen/logrus" ) // ListImages lists all the images in the store @@ -37,7 +38,7 @@ func (i *LibpodAPI) ListImages(call iopodman.VarlinkCall) error { if err != nil { return call.ReplyErrorOccurred(fmt.Sprintf("unable to get list of images %q", err)) } - var imageList []iopodman.ImageInList + var imageList []iopodman.Image for _, image := range images { labels, _ := image.Labels(getContext()) containers, _ := image.Containers() @@ -52,12 +53,12 @@ func (i *LibpodAPI) ListImages(call iopodman.VarlinkCall) error { return call.ReplyErrorOccurred(err.Error()) } - i := iopodman.ImageInList{ + i := iopodman.Image{ Id: image.ID(), ParentId: image.Parent, RepoTags: image.Names(), RepoDigests: repoDigests, - Created: image.Created().String(), + Created: image.Created().Format(time.RFC3339), Size: int64(*size), VirtualSize: image.VirtualSize, Containers: int64(len(containers)), @@ -69,11 +70,11 @@ func (i *LibpodAPI) ListImages(call iopodman.VarlinkCall) error { return call.ReplyListImages(imageList) } -// GetImage returns a single image in the form of a ImageInList -func (i *LibpodAPI) GetImage(call iopodman.VarlinkCall, name string) error { - newImage, err := i.Runtime.ImageRuntime().NewFromLocal(name) +// GetImage returns a single image in the form of a Image +func (i *LibpodAPI) GetImage(call iopodman.VarlinkCall, id string) error { + newImage, err := i.Runtime.ImageRuntime().NewFromLocal(id) if err != nil { - return call.ReplyImageNotFound(err.Error()) + return call.ReplyImageNotFound(id) } labels, err := newImage.Labels(getContext()) if err != nil { @@ -92,12 +93,12 @@ func (i *LibpodAPI) GetImage(call iopodman.VarlinkCall, name string) error { return err } - il := iopodman.ImageInList{ + il := iopodman.Image{ Id: newImage.ID(), ParentId: newImage.Parent, RepoTags: newImage.Names(), RepoDigests: repoDigests, - Created: newImage.Created().String(), + Created: newImage.Created().Format(time.RFC3339), Size: int64(*size), VirtualSize: newImage.VirtualSize, Containers: int64(len(containers)), @@ -240,7 +241,7 @@ func (i *LibpodAPI) BuildImage(call iopodman.VarlinkCall, config iopodman.BuildI time.Sleep(1 * time.Second) break } - br := iopodman.BuildResponse{ + br := iopodman.MoreResponse{ Logs: log, } call.ReplyBuildImage(br) @@ -258,7 +259,7 @@ func (i *LibpodAPI) BuildImage(call iopodman.VarlinkCall, config iopodman.BuildI if err != nil { return call.ReplyErrorOccurred(err.Error()) } - br := iopodman.BuildResponse{ + br := iopodman.MoreResponse{ Logs: log, Id: newImage.ID(), } @@ -276,12 +277,6 @@ func build(runtime *libpod.Runtime, options imagebuildah.BuildOptions, dockerfil return c } -// CreateImage ... -// TODO With Pull being added, should we skip Create? -func (i *LibpodAPI) CreateImage(call iopodman.VarlinkCall) error { - return call.ReplyMethodNotImplemented("CreateImage") -} - // InspectImage returns an image's inspect information as a string that can be serialized. // Requires an image ID or name func (i *LibpodAPI) InspectImage(call iopodman.VarlinkCall, name string) error { @@ -315,7 +310,7 @@ func (i *LibpodAPI) HistoryImage(call iopodman.VarlinkCall, name string) error { for _, hist := range history { imageHistory := iopodman.ImageHistory{ Id: hist.ID, - Created: hist.Created.String(), + Created: hist.Created.Format(time.RFC3339), CreatedBy: hist.CreatedBy, Tags: newImage.Names(), Size: hist.Size, @@ -332,7 +327,6 @@ func (i *LibpodAPI) PushImage(call iopodman.VarlinkCall, name, tag string, tlsVe registryCreds *types.DockerAuthConfig manifestType string ) - newImage, err := i.Runtime.ImageRuntime().NewFromLocal(name) if err != nil { return call.ReplyImageNotFound(err.Error()) @@ -372,10 +366,59 @@ func (i *LibpodAPI) PushImage(call iopodman.VarlinkCall, name, tag string, tlsVe SignBy: signBy, } - if err := newImage.PushImageToHeuristicDestination(getContext(), destname, manifestType, "", signaturePolicy, nil, compress, so, &dockerRegistryOptions, nil); err != nil { - return call.ReplyErrorOccurred(err.Error()) + if call.WantsMore() { + call.Continues = true } - return call.ReplyPushImage(newImage.ID()) + + output := bytes.NewBuffer([]byte{}) + c := make(chan error) + go func() { + err := newImage.PushImageToHeuristicDestination(getContext(), destname, manifestType, "", signaturePolicy, output, compress, so, &dockerRegistryOptions, nil) + c <- err + close(c) + }() + + // TODO When pull output gets fixed for the remote client, we need to look into how we can turn below + // into something re-usable. it is in build too + var log []string + done := false + for { + line, err := output.ReadString('\n') + if err == nil { + log = append(log, line) + continue + } else if err == io.EOF { + select { + case err := <-c: + if err != nil { + logrus.Errorf("reading of output during push failed for %s", newImage.ID()) + return call.ReplyErrorOccurred(err.Error()) + } + done = true + default: + if !call.WantsMore() { + time.Sleep(1 * time.Second) + break + } + br := iopodman.MoreResponse{ + Logs: log, + } + call.ReplyPushImage(br) + log = []string{} + } + } else { + return call.ReplyErrorOccurred(err.Error()) + } + if done { + break + } + } + call.Continues = false + + br := iopodman.MoreResponse{ + Logs: log, + } + return call.ReplyPushImage(br) } // TagImage accepts an image name and tag as strings and tags an image in the local store. @@ -405,17 +448,21 @@ func (i *LibpodAPI) RemoveImage(call iopodman.VarlinkCall, name string, force bo return call.ReplyRemoveImage(newImage.ID()) } -// SearchImage searches all registries configured in /etc/containers/registries.conf for an image +// SearchImages searches all registries configured in /etc/containers/registries.conf for an image // Requires an image name and a search limit as int -func (i *LibpodAPI) SearchImage(call iopodman.VarlinkCall, name string, limit int64) error { +func (i *LibpodAPI) SearchImages(call iopodman.VarlinkCall, query string, limit *int64) error { sc := image.GetSystemContext("", "", false) registries, err := sysreg.GetRegistries() if err != nil { return call.ReplyErrorOccurred(fmt.Sprintf("unable to get system registries: %q", err)) } - var imageResults []iopodman.ImageSearch + var imageResults []iopodman.ImageSearchResult for _, reg := range registries { - results, err := docker.SearchRegistry(getContext(), sc, reg, name, int(limit)) + var lim = 1000 + if limit != nil { + lim = int(*limit) + } + results, err := docker.SearchRegistry(getContext(), sc, reg, query, lim) if err != nil { // If we are searching multiple registries, don't make something like an // auth error fatal. Unfortunately we cannot differentiate between auth @@ -426,7 +473,7 @@ func (i *LibpodAPI) SearchImage(call iopodman.VarlinkCall, name string, limit in return call.ReplyErrorOccurred(err.Error()) } for _, result := range results { - i := iopodman.ImageSearch{ + i := iopodman.ImageSearchResult{ Description: result.Description, Is_official: result.IsOfficial, Is_automated: result.IsAutomated, @@ -436,7 +483,7 @@ func (i *LibpodAPI) SearchImage(call iopodman.VarlinkCall, name string, limit in imageResults = append(imageResults, i) } } - return call.ReplySearchImage(imageResults) + return call.ReplySearchImages(imageResults) } // DeleteUnusedImages deletes any images that do not have containers associated with it. diff --git a/pkg/varlinkapi/system.go b/pkg/varlinkapi/system.go index 376502f21..3f32615ec 100644 --- a/pkg/varlinkapi/system.go +++ b/pkg/varlinkapi/system.go @@ -3,6 +3,7 @@ package varlinkapi import ( goruntime "runtime" "strings" + "time" "github.com/containers/libpod/cmd/podman/varlink" "github.com/containers/libpod/libpod" @@ -15,22 +16,14 @@ func (i *LibpodAPI) GetVersion(call iopodman.VarlinkCall) error { return err } - return call.ReplyGetVersion(iopodman.Version{ - Remote_api_version: versionInfo.RemoteAPIVersion, - Version: versionInfo.Version, - Go_version: versionInfo.GoVersion, - Git_commit: versionInfo.GitCommit, - Built: versionInfo.Built, - Os_arch: versionInfo.OsArch, - }) -} - -// Ping returns a simple string "OK" response for clients to make sure -// the service is working. -func (i *LibpodAPI) Ping(call iopodman.VarlinkCall) error { - return call.ReplyPing(iopodman.StringResponse{ - Message: "OK", - }) + return call.ReplyGetVersion( + versionInfo.Version, + versionInfo.GoVersion, + versionInfo.GitCommit, + time.Unix(versionInfo.Built, 0).Format(time.RFC3339), + versionInfo.OsArch, + versionInfo.RemoteAPIVersion, + ) } // GetInfo returns details about the podman host and its stores diff --git a/pkg/varlinkapi/util.go b/pkg/varlinkapi/util.go index a80c8db41..7f6f95d3b 100644 --- a/pkg/varlinkapi/util.go +++ b/pkg/varlinkapi/util.go @@ -15,7 +15,7 @@ func getContext() context.Context { return context.TODO() } -func makeListContainer(containerID string, batchInfo shared.BatchContainerStruct) iopodman.ListContainerData { +func makeListContainer(containerID string, batchInfo shared.BatchContainerStruct) iopodman.Container { var ( mounts []iopodman.ContainerMount ports []iopodman.ContainerPortMappings @@ -56,12 +56,12 @@ func makeListContainer(containerID string, batchInfo shared.BatchContainerStruct Ipc: ns.IPC, } - lc := iopodman.ListContainerData{ + lc := iopodman.Container{ Id: containerID, Image: batchInfo.ConConfig.RootfsImageName, Imageid: batchInfo.ConConfig.RootfsImageID, Command: batchInfo.ConConfig.Spec.Process.Args, - Createdat: batchInfo.ConConfig.CreatedTime.String(), + Createdat: batchInfo.ConConfig.CreatedTime.Format(time.RFC3339), Runningfor: time.Since(batchInfo.ConConfig.CreatedTime).String(), Status: batchInfo.ConState.String(), Ports: ports, @@ -107,7 +107,7 @@ func makeListPod(pod *libpod.Pod, batchInfo shared.PsOptions) (iopodman.ListPodD listPodsContainers = append(listPodsContainers, makeListPodContainers(ctr.ID(), batchInfo)) } listPod := iopodman.ListPodData{ - Createdat: pod.CreatedTime().String(), + Createdat: pod.CreatedTime().Format(time.RFC3339), Id: pod.ID(), Name: pod.Name(), Status: status, diff --git a/pkg/varlinkapi/volumes.go b/pkg/varlinkapi/volumes.go index ced394e90..d41b07065 100644 --- a/pkg/varlinkapi/volumes.go +++ b/pkg/varlinkapi/volumes.go @@ -36,3 +36,39 @@ func (i *LibpodAPI) VolumeRemove(call iopodman.VarlinkCall, options iopodman.Vol } return call.ReplyVolumeRemove(deletedVolumes) } + +// GetVolumes returns all the volumes known to the remote system +func (i *LibpodAPI) GetVolumes(call iopodman.VarlinkCall, args []string, all bool) error { + var ( + err error + reply []*libpod.Volume + volumes []iopodman.Volume + ) + if all { + reply, err = i.Runtime.GetAllVolumes() + } else { + for _, v := range args { + vol, err := i.Runtime.GetVolume(v) + if err != nil { + return err + } + reply = append(reply, vol) + } + } + if err != nil { + return call.ReplyErrorOccurred(err.Error()) + } + // Build the iopodman.volume struct for the return + for _, v := range reply { + newVol := iopodman.Volume{ + Driver: v.Driver(), + Labels: v.Labels(), + MountPoint: v.MountPoint(), + Name: v.Name(), + Options: v.Options(), + Scope: v.Scope(), + } + volumes = append(volumes, newVol) + } + return call.ReplyGetVolumes(volumes) +} |