summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml6
-rw-r--r--cmd/podman/common/volumes.go8
-rw-r--r--cmd/podman/containers/create.go5
-rw-r--r--cmd/podman/early_init_linux.go2
-rw-r--r--cmd/podman/root.go37
-rw-r--r--cmd/podman/system/connection/add.go2
-rw-r--r--completions/bash/podman24
-rw-r--r--docs/source/Tutorials.rst1
-rw-r--r--docs/source/markdown/podman-remote.1.md2
-rw-r--r--docs/source/markdown/podman.1.md3
-rw-r--r--docs/tutorials/README.md4
-rw-r--r--docs/tutorials/podman-go-bindings.md546
-rw-r--r--go.mod2
-rw-r--r--go.sum2
-rw-r--r--libpod/container_internal_linux.go2
-rw-r--r--libpod/runtime_img.go4
-rw-r--r--test/e2e/run_networking_test.go32
-rw-r--r--test/e2e/run_test.go8
-rw-r--r--test/system/005-info.bats4
-rw-r--r--test/system/010-images.bats2
-rw-r--r--test/system/015-help.bats8
-rw-r--r--test/system/030-run.bats4
-rw-r--r--test/system/060-mount.bats2
-rw-r--r--test/system/075-exec.bats4
-rw-r--r--test/system/120-load.bats18
-rw-r--r--test/system/200-pod.bats5
-rw-r--r--test/system/250-systemd.bats2
-rw-r--r--test/system/260-sdnotify.bats2
-rw-r--r--test/system/500-networking.bats4
-rw-r--r--vendor/github.com/containers/image/v5/docker/docker_client.go59
-rw-r--r--vendor/github.com/containers/image/v5/version/version.go2
-rw-r--r--vendor/modules.txt2
32 files changed, 732 insertions, 76 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index 91e94dd47..964368743 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -417,8 +417,6 @@ testing_task:
gce_instance:
image_name: "${PRIOR_UBUNTU_CACHE_IMAGE_NAME}"
- timeout_in: 120m
-
env:
ADD_SECOND_PARTITION: 'true'
matrix:
@@ -473,8 +471,6 @@ special_testing_rootless_task:
- RCLI: 'true'
- RCLI: 'false'
- timeout_in: 60m
-
networking_script: '${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/networking.sh'
setup_environment_script: '$SCRIPT_BASE/setup_environment.sh |& ${TIMESTAMP}'
integration_test_script: '$SCRIPT_BASE/integration_test.sh |& ${TIMESTAMP} | ${LOGFORMAT} integration_test'
@@ -515,8 +511,6 @@ special_testing_in_podman_task:
MOD_CONTAINERS_CONF: 'false' # Use existing/native setup
SPECIALMODE: 'in_podman' # See docs
- timeout_in: 60m
-
networking_script: '${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/networking.sh'
setup_environment_script: '$SCRIPT_BASE/setup_environment.sh |& ${TIMESTAMP}'
integration_test_script: '$SCRIPT_BASE/integration_test.sh |& ${TIMESTAMP} | ${LOGFORMAT} integration_test'
diff --git a/cmd/podman/common/volumes.go b/cmd/podman/common/volumes.go
index 20c31bd81..ca0b10765 100644
--- a/cmd/podman/common/volumes.go
+++ b/cmd/podman/common/volumes.go
@@ -88,17 +88,11 @@ func parseVolumes(volumeFlag, mountFlag, tmpfsFlag []string, addReadOnlyTmpfs bo
if _, ok := unifiedVolumes[dest]; ok {
continue
}
- localOpts := options
- if dest == "/run" {
- localOpts = append(localOpts, "noexec", "size=65536k")
- } else {
- localOpts = append(localOpts, "exec")
- }
unifiedMounts[dest] = spec.Mount{
Destination: dest,
Type: TypeTmpfs,
Source: "tmpfs",
- Options: localOpts,
+ Options: options,
}
}
}
diff --git a/cmd/podman/containers/create.go b/cmd/podman/containers/create.go
index 6eec93f98..801547033 100644
--- a/cmd/podman/containers/create.go
+++ b/cmd/podman/containers/create.go
@@ -297,7 +297,12 @@ func createPodIfNecessary(s *specgen.SpecGenerator, netOpts *entities.NetOptions
Infra: true,
Net: netOpts,
CreateCommand: os.Args,
+ Hostname: s.ContainerBasicConfig.Hostname,
}
+ // Unset config values we passed to the pod to prevent them being used twice for the container and pod.
+ s.ContainerBasicConfig.Hostname = ""
+ s.ContainerNetworkConfig = specgen.ContainerNetworkConfig{}
+
s.Pod = podName
return registry.ContainerEngine().PodCreate(context.Background(), createOptions)
}
diff --git a/cmd/podman/early_init_linux.go b/cmd/podman/early_init_linux.go
index e2893ff69..4e232a0b0 100644
--- a/cmd/podman/early_init_linux.go
+++ b/cmd/podman/early_init_linux.go
@@ -32,7 +32,7 @@ func setUMask() {
func earlyInitHook() {
if err := setRLimits(); err != nil {
- fmt.Fprint(os.Stderr, "Failed to set rlimits: "+err.Error())
+ fmt.Fprintf(os.Stderr, "Failed to set rlimits: %s\n", err.Error())
}
setUMask()
diff --git a/cmd/podman/root.go b/cmd/podman/root.go
index dd9c75ece..8f77e5893 100644
--- a/cmd/podman/root.go
+++ b/cmd/podman/root.go
@@ -111,6 +111,30 @@ func persistentPreRunE(cmd *cobra.Command, args []string) error {
cfg := registry.PodmanConfig()
+ // --connection is not as "special" as --remote so we can wait and process it here
+ var connErr error
+ conn := cmd.Root().LocalFlags().Lookup("connection")
+ if conn != nil && conn.Changed {
+ cfg.Engine.ActiveService = conn.Value.String()
+
+ var err error
+ cfg.URI, cfg.Identity, err = cfg.ActiveDestination()
+ if err != nil {
+ connErr = errors.Wrap(err, "failed to resolve active destination")
+ }
+
+ if err := cmd.Root().LocalFlags().Set("url", cfg.URI); err != nil {
+ connErr = errors.Wrap(err, "failed to override --url flag")
+ }
+
+ if err := cmd.Root().LocalFlags().Set("identity", cfg.Identity); err != nil {
+ connErr = errors.Wrap(err, "failed to override --identity flag")
+ }
+ }
+ if connErr != nil {
+ return connErr
+ }
+
// Prep the engines
if _, err := registry.NewImageEngine(cmd, args); err != nil {
return err
@@ -226,10 +250,11 @@ func loggingHook() {
func rootFlags(cmd *cobra.Command, opts *entities.PodmanConfig) {
cfg := opts.Config
- uri, ident := resolveDestination()
+ srv, uri, ident := resolveDestination()
lFlags := cmd.Flags()
lFlags.BoolVarP(&opts.Remote, "remote", "r", false, "Access remote Podman service (default false)")
+ lFlags.StringVarP(&opts.Engine.ActiveService, "connection", "c", srv, "Connection to use for remote Podman service")
lFlags.StringVar(&opts.URI, "url", uri, "URL to access Podman service (CONTAINER_HOST)")
lFlags.StringVar(&opts.Identity, "identity", ident, "path to SSH identity file, (CONTAINER_SSHKEY)")
@@ -279,24 +304,24 @@ func rootFlags(cmd *cobra.Command, opts *entities.PodmanConfig) {
}
}
-func resolveDestination() (string, string) {
+func resolveDestination() (string, string, string) {
if uri, found := os.LookupEnv("CONTAINER_HOST"); found {
var ident string
if v, found := os.LookupEnv("CONTAINER_SSHKEY"); found {
ident = v
}
- return uri, ident
+ return "", uri, ident
}
cfg, err := config.ReadCustomConfig()
if err != nil {
logrus.Warning(errors.Wrap(err, "unable to read local containers.conf"))
- return registry.DefaultAPIAddress(), ""
+ return "", registry.DefaultAPIAddress(), ""
}
uri, ident, err := cfg.ActiveDestination()
if err != nil {
- return registry.DefaultAPIAddress(), ""
+ return "", registry.DefaultAPIAddress(), ""
}
- return uri, ident
+ return cfg.Engine.ActiveService, uri, ident
}
diff --git a/cmd/podman/system/connection/add.go b/cmd/podman/system/connection/add.go
index af13b970c..8b9ab6dbb 100644
--- a/cmd/podman/system/connection/add.go
+++ b/cmd/podman/system/connection/add.go
@@ -95,7 +95,7 @@ func add(cmd *cobra.Command, args []string) error {
uri.Host = net.JoinHostPort(uri.Hostname(), cmd.Flag("port").DefValue)
}
- if uri.Path == "" {
+ if uri.Path == "" || uri.Path == "/" {
if uri.Path, err = getUDS(cmd, uri); err != nil {
return errors.Wrapf(err, "failed to connect to %q", uri.String())
}
diff --git a/completions/bash/podman b/completions/bash/podman
index f0c8e7394..379ba7fc8 100644
--- a/completions/bash/podman
+++ b/completions/bash/podman
@@ -3602,22 +3602,32 @@ _podman_volume() {
_podman_podman() {
local options_with_args="
- --config -c
+ --cni-config-dir
+ --conmon
+ --connection -c
+ --events-backend
+ --hooks-dir
+ --identity
+ --log-level
+ --namespace
+ --network-cmd-path
--root
--runroot
--storage-driver
--storage-opt
- --log-level
- --namespace
- "
+ --tmpdir
+ --runtime
+ --url
+ "
local boolean_options="
--help
- -h
+ --syslog
--version
+ -h
+ -r, --remote
-v
- --syslog
"
- commands="
+ commands="
attach
auto-update
build
diff --git a/docs/source/Tutorials.rst b/docs/source/Tutorials.rst
index 1b17bc4c7..33e4ae3d3 100644
--- a/docs/source/Tutorials.rst
+++ b/docs/source/Tutorials.rst
@@ -10,3 +10,4 @@ Here are a number of useful tutorials to get you up and running with Podman. If
* `How to sign and distribute container images using Podman <https://github.com/containers/podman/blob/master/docs/tutorials/image_signing.md>`_: Learn how to setup and use image signing with Podman.
* `Podman remote-client tutorial <https://github.com/containers/podman/blob/master/docs/tutorials/remote_client.md>`_: A brief how-to on using the Podman remote-client.
* `How to use libpod for custom/derivative projects <https://github.com/containers/podman/blob/master/docs/tutorials/podman-derivative-api.md>`_: How the libpod API can be used within your own project.
+* `How to use Podman's Go bindings <https://github.com/containers/podman/blob/master/docs/tutorials/podman-go-bindings.md>`_: A brief how-to on using Podman's Go bindings in external applications.
diff --git a/docs/source/markdown/podman-remote.1.md b/docs/source/markdown/podman-remote.1.md
index 0d7be1e5d..23ccaf0e6 100644
--- a/docs/source/markdown/podman-remote.1.md
+++ b/docs/source/markdown/podman-remote.1.md
@@ -23,7 +23,7 @@ Podman-remote provides a local client interacting with a Podman backend node thr
## GLOBAL OPTIONS
-**--connection**=*name*
+**--connection**=*name*, **-c**
Remote connection name
diff --git a/docs/source/markdown/podman.1.md b/docs/source/markdown/podman.1.md
index 16439c167..c53da6b5f 100644
--- a/docs/source/markdown/podman.1.md
+++ b/docs/source/markdown/podman.1.md
@@ -31,6 +31,9 @@ Note: CGroup manager is not supported in rootless mode when using CGroups Versio
**--cni-config-dir**
Path of the configuration directory for CNI networks. (Default: `/etc/cni/net.d`)
+**--connection**, **-c**
+Connection to use for remote podman (Default connection is configured in `containers.conf`)
+
**--conmon**
Path of the conmon binary (Default path is configured in `containers.conf`)
diff --git a/docs/tutorials/README.md b/docs/tutorials/README.md
index 191d7a4b5..4beb069ac 100644
--- a/docs/tutorials/README.md
+++ b/docs/tutorials/README.md
@@ -27,3 +27,7 @@ How the libpod API can be used within your own project.
**[Image Signing](image_signing.md)**
Learn how to setup and use image signing with Podman.
+
+**[Go Bindings](podman-go-bindings.md)**
+
+A brief how-to on using Podman's Go bindings in external applications.
diff --git a/docs/tutorials/podman-go-bindings.md b/docs/tutorials/podman-go-bindings.md
new file mode 100644
index 000000000..ddebf7e99
--- /dev/null
+++ b/docs/tutorials/podman-go-bindings.md
@@ -0,0 +1,546 @@
+![PODMAN logo](../../logo/podman-logo-source.svg)
+
+# Podman Go bindings
+
+## Introduction
+
+In the release of Podman 2.0, we removed the experimental tag
+from its recently introduced RESTful service. While it might
+be interesting to interact with a RESTFul server using curl,
+using a set of Go based bindings is probably a more direct
+route to a production ready application. Let’s take a look
+at how easily that can be accomplished.
+
+If you haven't yet, [install Go](https://golang.org/doc/install).
+
+Be careful to double-check that the version of golang is new
+enough (i.e. `go version`), version 1.13.x or higher is
+supported. If needed, Go sources and binaries can be fetched
+from the [official Go website](https://golang.org/dl/).
+
+The Podman Go bindings are a set of functions to allow
+developers to execute Podman operations from within their Go
+based application. The Go bindings connect to a Podman service
+which can run locally or on a remote machine. You can perform
+many operations including pulling and listing images, starting,
+stopping or inspecting containers. Currently, the Podman
+repository has bindings available for operations on images,
+containers, pods, networks and manifests among others. The
+bindings are available on the [v2.0 branch in the
+upstream Podman repository](https://github.com/containers/podman/tree/v2.0).
+You can fetch the bindings for your application using Go modules:
+
+```bash
+$ cd $HOME
+$ mkdir example && cd example
+$ go mod init example.com
+go: creating new go.mod: module example.com
+$ go get github.com/containers/podman/v2@v2.0.4
+go: downloading github.com/containers/podman/v2 v2.0.4
+go get: github.com/containers/podman/v2@v2.0.4: parsing go.mod:
+ module declares its path as: github.com/containers/libpod/v2
+ but was required as: github.com/containers/podman/v2
+```
+
+This creates a new `go.mod` file in the current directory that looks as follows:
+
+```bash
+module example.com
+
+go 1.14
+
+require github.com/containers/libpod/v2 v2.0.4 // indirect
+```
+
+You can also try a demo application with the Go modules created already:
+
+```bash
+$ git clone https://github.com/containers/Demos
+$ cd Demos/podman_go_bindings
+$ ls
+README.md go.mod go.sum main.go
+```
+
+
+## How do I use them
+
+In this tutorial, you will learn through basic examples how to:
+
+0. [Start the Podman system service](#start-service)
+1. [Connect to the Podman system service](#connect-service)
+2. [Pull images](#pull-images)
+3. [List images](#list-images)
+4. [Create and start a container from an image](#create-start-container)
+5. [List containers](#list-containers)
+6. [Inspect the container](#inspect-container)
+7. [Stop the container](#stop-container)
+8. [Debugging tips](#debugging-tips)
+
+
+### Start the Podman system service <a name="start-service"></a>
+The recommended way to start Podman system service in production mode
+is via systemd socket-activation:
+
+```bash
+$ systemctl --user start podman.socket
+```
+
+There’s no timeout specified when starting the system service via socket-activation.
+
+For purposes of this demo, we will start the service using the Podman
+command itself. If you prefer the system service to timeout after, say,
+5000 seconds, you can run it like so:
+
+```bash
+$ podman system service -t 5000
+```
+
+Note that the 5000 seconds uptime is refreshed after every command is received.
+If you want the service to stay up until the machine is shutdown or the process
+is terminated, use `0` (zero) instead of 5000. For this demo, we will use no timeout:
+
+```bash
+$ podman system service -t 0
+```
+
+
+Open another terminal window and check if the Podman socket exists:
+
+```bash
+$ ls /run/user/${UID}/podman
+podman.sock
+```
+
+If you’re running the system service as root, podman.sock will be found in /run/podman:
+```bash
+# ls /run/podman
+podman.sock
+```
+
+
+### Connect to the Podman system service <a name="connect-service"></a>
+First, you need to create a connection that connects to the system service.
+The critical piece of information for setting up a new connection is the endpoint.
+The endpoint comes in the form of an URI (method:/path/to/socket). For example,
+to connect to the local rootful socket the URI would be `unix:/run/podman/podman.sock`
+and for a rootless user it would be `unix:$(XDG_RUNTIME_DIR)/podman/podman.sock`,
+typically: `unix:/run/user/${UID}/podman/podman.sock`.
+
+
+The following Go example snippet shows how to set up a connection for a rootless user.
+```Go
+package main
+
+import (
+ "context"
+ "fmt"
+ "os"
+
+ "github.com/containers/libpod/v2/libpod/define"
+ "github.com/containers/libpod/v2/pkg/bindings"
+ "github.com/containers/libpod/v2/pkg/bindings/containers"
+ "github.com/containers/libpod/v2/pkg/bindings/images"
+ "github.com/containers/libpod/v2/pkg/domain/entities"
+ "github.com/containers/libpod/v2/pkg/specgen"
+)
+
+func main() {
+ fmt.Println("Welcome to the Podman Go bindings tutorial")
+
+ // Get Podman socket location
+ sock_dir := os.Getenv("XDG_RUNTIME_DIR")
+ socket := "unix:" + sock_dir + "/podman/podman.sock"
+
+ // Connect to Podman socket
+ connText, err := bindings.NewConnection(context.Background(), socket)
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+}
+```
+
+The `connText` variable received from the NewConnection function is of type
+context.Context(). In subsequent uses of the bindings, you will use this context
+to direct the bindings to your connection. This can be seen in the examples below.
+
+### Pull an image <a name="pull-images"></a>
+
+Next, we will pull a couple of images using the images.Pull() binding.
+This binding takes three arguments:
+ - The context variable created by the bindings.NewConnection() call in the first example
+ - The image name
+ - Options for image pull
+
+**Append the following lines to your function:**
+
+```Go
+ // Pull Busybox image (Sample 1)
+ fmt.Println("Pulling Busybox image...")
+ _, err = images.Pull(connText, "docker.io/busybox", entities.ImagePullOptions{})
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+
+ // Pull Fedora image (Sample 2)
+ rawImage := "registry.fedoraproject.org/fedora:latest"
+ fmt.Println("Pulling Fedora image...")
+ _, err = images.Pull(connText, rawImage, entities.ImagePullOptions{})
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+```
+
+**Run it:**
+
+```bash
+$ go run main.go
+Welcome to the Podman Go bindings tutorial
+Pulling Busybox image...
+Pulling Fedora image...
+$
+```
+
+The system service side should echo messages like so:
+
+```bash
+Trying to pull docker.io/busybox...
+Getting image source signatures
+Copying blob 61c5ed1cbdf8 [--------------------------------------] 0.0b / 0.0b
+Copying config 018c9d7b79 done
+Writing manifest to image destination
+Storing signatures
+Trying to pull registry.fedoraproject.org/fedora:latest...
+Getting image source signatures
+Copying blob dd9f43919ba0 [--------------------------------------] 0.0b / 0.0b
+Copying config 00ff39a8bf done
+Writing manifest to image destination
+Storing signatures
+```
+
+
+### List images <a name="list-images"></a>
+Next, we will pull an image using the images.List() binding.
+This binding takes three arguments:
+ - The context variable created earlier
+ - An optional bool 'all'
+ - An optional map of filters
+
+**Append the following lines to your function:**
+
+```Go
+ // List images
+ imageSummary, err := images.List(connText, nil, nil)
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+ var names []string
+ for _, i := range imageSummary {
+ names = append(names, i.RepoTags...)
+ }
+ fmt.Println("Listing images...")
+ fmt.Println(names)
+```
+
+**Run it:**
+
+```bash
+$ go run main.go
+Welcome to the Podman Go bindings tutorial
+Pulling Busybox image...
+Pulling Fedora image...
+Listing images...
+[docker.io/library/busybox:latest registry.fedoraproject.org/fedora:latest]
+$
+```
+
+
+### Create and Start a Container from an Image <a name="create-start-container"></a>
+
+To create the container spec, we use specgen.NewSpecGenerator() followed by
+calling containers.CreateWithSpec() to actually create a new container.
+specgen.NewSpecGenerator() takes 2 arguments:
+ - name of the image
+ - whether it's a rootfs
+
+containers.CreateWithSpec() takes 2 arguments:
+ - the context created earlier
+ - the spec created by NewSpecGenerator
+
+Next, the container is actually started using the containers.Start() binding.
+containers.Start() takes three arguments:
+ - the context
+ - the name or ID of the container created
+ - an optional parameter for detach keys
+
+After the container is started, it's a good idea to ensure the container is
+in a running state before you proceed with further operations.
+The containers.Wait() takes care of that.
+containers.Wait() takes three arguments:
+ - the context
+ - the name or ID of the container created
+ - container state (running/paused/stopped)
+
+**Append the following lines to your function:**
+
+```Go
+ // Container create
+ s := specgen.NewSpecGenerator(rawImage, false)
+ s.Terminal = true
+ r, err := containers.CreateWithSpec(connText, s)
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+
+ // Container start
+ fmt.Println("Starting Fedora container...")
+ err = containers.Start(connText, r.ID, nil)
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+
+ running := define.ContainerStateRunning
+ _, err = containers.Wait(connText, r.ID, &running)
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+```
+
+**Run it:**
+
+```bash
+$ go run main.go
+Welcome to the Podman Go bindings tutorial
+Pulling image...
+Starting Fedora container...
+$
+```
+
+Check if the container is running:
+
+```bash
+$ podman ps
+CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
+665831d31e90 registry.fedoraproject.org/fedora:latest /bin/bash Less than a second ago Up Less than a second ago dazzling_mclean
+$
+```
+
+
+### List Containers <a name="list-containers"></a>
+
+Containers can be listed using the containers.List() binding.
+containers.List() takes seven arguments:
+ - the context
+ - output filters
+ - boolean to show all containers, by default only running containers are listed
+ - number of latest created containers, all states (running/paused/stopped)
+ - boolean to print pod information
+ - boolean to print rootfs size
+ - boolean to print oci runtime and container state
+
+**Append the following lines to your function:**
+
+```Go
+ // Container list
+ var latestContainers = 1
+ containerLatestList, err := containers.List(connText, nil, nil, &latestContainers, nil, nil, nil)
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+ fmt.Printf("Latest container is %s\n", containerLatestList[0].Names[0])
+```
+
+**Run it:**
+
+```bash
+$ go run main.go
+Welcome to the Podman Go bindings tutorial
+Pulling Busybox image...
+Pulling Fedora image...
+Listing images...
+[docker.io/library/busybox:latest registry.fedoraproject.org/fedora:latest]
+Starting Fedora container...
+Latest container is dazzling_mclean
+$
+```
+
+
+### Inspect Container <a name="inspect-container"></a>
+Containers can be inspected using the containers.Inspect() binding.
+containers.Inspect() takes 3 arguments:
+ - context
+ - image name or ID
+ - optional boolean to check for container size
+
+
+**Append the following lines to your function:**
+
+```Go
+ // Container inspect
+ ctrData, err := containers.Inspect(connText, r.ID, nil)
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+ fmt.Printf("Container uses image %s\n", ctrData.ImageName)
+ fmt.Printf("Container running status is %s\n", ctrData.State.Status)
+```
+
+**Run it:**
+
+```bash
+$ go run main.go
+Welcome to the Podman Go bindings tutorial
+Pulling Busybox image...
+Pulling Fedora image...
+Listing images...
+[docker.io/library/busybox:latest registry.fedoraproject.org/fedora:latest]
+Starting Fedora container...
+Latest container is peaceful_noether
+Fedora Container uses image registry.fedoraproject.org/fedora:latest
+Fedora Container running status is running
+$
+```
+
+
+### Stop Container <a name="stop-container"></a>
+
+A container can be stopped by the containers.Stop() binding.
+containers.Stop() takes 3 arguments:
+ - context
+ - image name or ID
+ - optional timeout
+
+**Append the following lines to your function:**
+
+```Go
+ // Container stop
+ fmt.Println("Stopping the container...")
+ err = containers.Stop(connText, r.ID, nil)
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+ ctrData, err = containers.Inspect(connText, r.ID, nil)
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+ fmt.Printf("Container running status is now %s\n", ctrData.State.Status)
+```
+
+**Run it:**
+
+```bash
+$ go run main.go
+Welcome to the Podman Go bindings tutorial
+Pulling Busybox image...
+Pulling Fedora image...
+Listing images...
+[docker.io/library/busybox:latest registry.fedoraproject.org/fedora:latest]
+Starting Fedora container...
+Latest container is peaceful_noether
+Fedora Container uses image registry.fedoraproject.org/fedora:latest
+Fedora Container running status is running
+Stopping Fedora container...
+Container running status is now exited
+```
+
+
+### Debugging tips <a name="debugging-tips"></a>
+
+To debug in a development setup, you can start the Podman system service
+in debug mode like so:
+
+```bash
+$ podman --log-level=debug system service -t 0
+```
+
+The `--log-level=debug` echoes all the logged requests and is useful to
+trace the execution path at a finer granularity. A snippet of a sample run looks like:
+
+```bash
+INFO[0000] podman filtering at log level debug
+DEBU[0000] Called service.PersistentPreRunE(podman --log-level=debug system service -t0)
+DEBU[0000] Ignoring libpod.conf EventsLogger setting "/home/lsm5/.config/containers/containers.conf". Use "journald" if you want to change this setting and remove libpod.conf files.
+DEBU[0000] Reading configuration file "/usr/share/containers/containers.conf"
+DEBU[0000] Merged system config "/usr/share/containers/containers.conf": {Editors note: the remainder of this line was removed due to Jekyll formatting errors.}
+DEBU[0000] Using conmon: "/usr/bin/conmon"
+DEBU[0000] Initializing boltdb state at /home/lsm5/.local/share/containers/storage/libpod/bolt_state.db
+DEBU[0000] Overriding run root "/run/user/1000/containers" with "/run/user/1000" from database
+DEBU[0000] Using graph driver overlay
+DEBU[0000] Using graph root /home/lsm5/.local/share/containers/storage
+DEBU[0000] Using run root /run/user/1000
+DEBU[0000] Using static dir /home/lsm5/.local/share/containers/storage/libpod
+DEBU[0000] Using tmp dir /run/user/1000/libpod/tmp
+DEBU[0000] Using volume path /home/lsm5/.local/share/containers/storage/volumes
+DEBU[0000] Set libpod namespace to ""
+DEBU[0000] Not configuring container store
+DEBU[0000] Initializing event backend file
+DEBU[0000] using runtime "/usr/bin/runc"
+DEBU[0000] using runtime "/usr/bin/crun"
+WARN[0000] Error initializing configured OCI runtime kata: no valid executable found for OCI runtime kata: invalid argument
+DEBU[0000] using runtime "/usr/bin/crun"
+INFO[0000] Setting parallel job count to 25
+INFO[0000] podman filtering at log level debug
+DEBU[0000] Called service.PersistentPreRunE(podman --log-level=debug system service -t0)
+DEBU[0000] Ignoring libpod.conf EventsLogger setting "/home/lsm5/.config/containers/containers.conf". Use "journald" if you want to change this setting and remove libpod.conf files.
+DEBU[0000] Reading configuration file "/usr/share/containers/containers.conf"
+```
+
+If the Podman system service has been started via systemd socket activation,
+you can view the logs using journalctl. The logs after a sample run look like so:
+
+```bash
+$ journalctl --user --no-pager -u podman.socket
+-- Reboot --
+Jul 22 13:50:40 nagato.nanadai.me systemd[1048]: Listening on Podman API Socket.
+$
+```
+
+```bash
+$ journalctl --user --no-pager -u podman.service
+Jul 22 13:50:53 nagato.nanadai.me systemd[1048]: Starting Podman API Service...
+Jul 22 13:50:54 nagato.nanadai.me podman[1527]: time="2020-07-22T13:50:54-04:00" level=error msg="Error refreshing volume 38480630a8bdaa3e1a0ebd34c94038591b0d7ad994b37be5b4f2072bb6ef0879: error acquiring lock 0 for volume 38480630a8bdaa3e1a0ebd34c94038591b0d7ad994b37be5b4f2072bb6ef0879: file exists"
+Jul 22 13:50:54 nagato.nanadai.me podman[1527]: time="2020-07-22T13:50:54-04:00" level=error msg="Error refreshing volume 47d410af4d762a0cc456a89e58f759937146fa3be32b5e95a698a1d4069f4024: error acquiring lock 0 for volume 47d410af4d762a0cc456a89e58f759937146fa3be32b5e95a698a1d4069f4024: file exists"
+Jul 22 13:50:54 nagato.nanadai.me podman[1527]: time="2020-07-22T13:50:54-04:00" level=error msg="Error refreshing volume 86e73f082e344dad38c8792fb86b2017c4f133f2a8db87f239d1d28a78cf0868: error acquiring lock 0 for volume 86e73f082e344dad38c8792fb86b2017c4f133f2a8db87f239d1d28a78cf0868: file exists"
+Jul 22 13:50:54 nagato.nanadai.me podman[1527]: time="2020-07-22T13:50:54-04:00" level=error msg="Error refreshing volume 9a16ea764be490a5563e384d9074ab0495e4d9119be380c664037d6cf1215631: error acquiring lock 0 for volume 9a16ea764be490a5563e384d9074ab0495e4d9119be380c664037d6cf1215631: file exists"
+Jul 22 13:50:54 nagato.nanadai.me podman[1527]: time="2020-07-22T13:50:54-04:00" level=error msg="Error refreshing volume bfd6b2a97217f8655add13e0ad3f6b8e1c79bc1519b7a1e15361a107ccf57fc0: error acquiring lock 0 for volume bfd6b2a97217f8655add13e0ad3f6b8e1c79bc1519b7a1e15361a107ccf57fc0: file exists"
+Jul 22 13:50:54 nagato.nanadai.me podman[1527]: time="2020-07-22T13:50:54-04:00" level=error msg="Error refreshing volume f9b9f630982452ebcbed24bd229b142fbeecd5d4c85791fca440b21d56fef563: error acquiring lock 0 for volume f9b9f630982452ebcbed24bd229b142fbeecd5d4c85791fca440b21d56fef563: file exists"
+Jul 22 13:50:54 nagato.nanadai.me podman[1527]: Trying to pull registry.fedoraproject.org/fedora:latest...
+Jul 22 13:50:55 nagato.nanadai.me podman[1527]: Getting image source signatures
+Jul 22 13:50:55 nagato.nanadai.me podman[1527]: Copying blob sha256:dd9f43919ba05f05d4f783c31e83e5e776c4f5d29dd72b9ec5056b9576c10053
+Jul 22 13:50:55 nagato.nanadai.me podman[1527]: Copying config sha256:00ff39a8bf19f810a7e641f7eb3ddc47635913a19c4996debd91fafb6b379069
+Jul 22 13:50:55 nagato.nanadai.me podman[1527]: Writing manifest to image destination
+Jul 22 13:50:55 nagato.nanadai.me podman[1527]: Storing signatures
+Jul 22 13:50:55 nagato.nanadai.me systemd[1048]: podman.service: unit configures an IP firewall, but not running as root.
+Jul 22 13:50:55 nagato.nanadai.me systemd[1048]: (This warning is only shown for the first unit using IP firewalling.)
+Jul 22 13:51:15 nagato.nanadai.me systemd[1048]: podman.service: Succeeded.
+Jul 22 13:51:15 nagato.nanadai.me systemd[1048]: Finished Podman API Service.
+Jul 22 13:51:15 nagato.nanadai.me systemd[1048]: podman.service: Consumed 1.339s CPU time.
+$
+```
+
+
+## Wrap Up
+Podman v2 provides a set of Go bindings to allow developers to integrate Podman
+functionality conveniently in their Go application. These Go bindings require
+the Podman system service to be running in the background and this can easily
+be achieved using systemd socket activation. Once set up, you are able to use a
+set of Go based bindings to create, maintain and monitor your container images,
+containers and pods in a way which fits very nicely in many production environments.
+
+
+## References
+- Podman v2 is available for most major distributions along with MacOS and Windows.
+Installation details are available on the [Podman official website](https://podman.io/getting-started/).
+
+- Documentation can be found at the [Podman Docs page](https://docs.podman.io).
+It also includes a section on the [RESTful API](https://docs.podman.io/en/latest/Reference.html).
diff --git a/go.mod b/go.mod
index ea2ac5db6..3a3173418 100644
--- a/go.mod
+++ b/go.mod
@@ -13,7 +13,7 @@ require (
github.com/containers/buildah v1.15.1-0.20200731151214-29f4d01c621c
github.com/containers/common v0.18.0
github.com/containers/conmon v2.0.19+incompatible
- github.com/containers/image/v5 v5.5.1
+ github.com/containers/image/v5 v5.5.2
github.com/containers/psgo v1.5.1
github.com/containers/storage v1.23.0
github.com/coreos/go-systemd/v22 v22.1.0
diff --git a/go.sum b/go.sum
index 0ec2e0078..d2a3f91f1 100644
--- a/go.sum
+++ b/go.sum
@@ -79,6 +79,8 @@ github.com/containers/conmon v2.0.19+incompatible h1:1bDVRvHy2MUNTUT/SW6LlHsJHQB
github.com/containers/conmon v2.0.19+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
github.com/containers/image/v5 v5.5.1 h1:h1FCOXH6Ux9/p/E4rndsQOC4yAdRU0msRTfLVeQ7FDQ=
github.com/containers/image/v5 v5.5.1/go.mod h1:4PyNYR0nwlGq/ybVJD9hWlhmIsNra4Q8uOQX2s6E2uM=
+github.com/containers/image/v5 v5.5.2 h1:fv7FArz0zUnjH0W0l8t90CqWFlFcQrPP6Pug+9dUtVI=
+github.com/containers/image/v5 v5.5.2/go.mod h1:4PyNYR0nwlGq/ybVJD9hWlhmIsNra4Q8uOQX2s6E2uM=
github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b h1:Q8ePgVfHDplZ7U33NwHZkrVELsZP5fYj9pM5WBZB2GE=
github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY=
github.com/containers/ocicrypt v1.0.2/go.mod h1:nsOhbP19flrX6rE7ieGFvBlr7modwmNjsqWarIUce4M=
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index fdee3877c..ea4340e00 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -571,7 +571,7 @@ func (c *Container) setupSystemd(mounts []spec.Mount, g generate.Generator) erro
Destination: dest,
Type: "tmpfs",
Source: "tmpfs",
- Options: append(options, "tmpcopyup", "size=65536k"),
+ Options: append(options, "tmpcopyup"),
}
g.AddMount(tmpfsMnt)
}
diff --git a/libpod/runtime_img.go b/libpod/runtime_img.go
index a95cd1d7a..2bc9feb65 100644
--- a/libpod/runtime_img.go
+++ b/libpod/runtime_img.go
@@ -144,6 +144,10 @@ func storageContainers(imageID string, store storage.Store) ([]string, error) {
// Removes the containers passed in the array.
func removeStorageContainers(ctrIDs []string, store storage.Store) error {
for _, ctrID := range ctrIDs {
+ if _, err := store.Unmount(ctrID, true); err != nil {
+ return errors.Wrapf(err, "could not unmount container %q to remove it", ctrID)
+ }
+
if err := store.DeleteContainer(ctrID); err != nil {
return errors.Wrapf(err, "could not remove container %q", ctrID)
}
diff --git a/test/e2e/run_networking_test.go b/test/e2e/run_networking_test.go
index 83befe730..a48f7c83e 100644
--- a/test/e2e/run_networking_test.go
+++ b/test/e2e/run_networking_test.go
@@ -531,8 +531,8 @@ var _ = Describe("Podman run networking", func() {
SkipIfRemote()
SkipIfRootless()
netName := "podmantestnetwork"
- ipAddr := "10.20.30.128"
- create := podmanTest.Podman([]string{"network", "create", "--subnet", "10.20.30.0/24", netName})
+ ipAddr := "10.25.30.128"
+ create := podmanTest.Podman([]string{"network", "create", "--subnet", "10.25.30.0/24", netName})
create.WaitWithDefaultTimeout()
Expect(create.ExitCode()).To(BeZero())
@@ -540,5 +540,33 @@ var _ = Describe("Podman run networking", func() {
run.WaitWithDefaultTimeout()
Expect(run.ExitCode()).To(BeZero())
Expect(run.OutputToString()).To(ContainSubstring(ipAddr))
+
+ netrm := podmanTest.Podman([]string{"network", "rm", netName})
+ netrm.WaitWithDefaultTimeout()
+ Expect(netrm.ExitCode()).To(BeZero())
+ })
+
+ It("podman run with new:pod and static-ip", func() {
+ SkipIfRemote()
+ SkipIfRootless()
+ netName := "podmantestnetwork2"
+ ipAddr := "10.25.40.128"
+ podname := "testpod"
+ create := podmanTest.Podman([]string{"network", "create", "--subnet", "10.25.40.0/24", netName})
+ create.WaitWithDefaultTimeout()
+ Expect(create.ExitCode()).To(BeZero())
+
+ run := podmanTest.Podman([]string{"run", "-t", "-i", "--rm", "--pod", "new:" + podname, "--net", netName, "--ip", ipAddr, ALPINE, "ip", "addr"})
+ run.WaitWithDefaultTimeout()
+ Expect(run.ExitCode()).To(BeZero())
+ Expect(run.OutputToString()).To(ContainSubstring(ipAddr))
+
+ podrm := podmanTest.Podman([]string{"pod", "rm", "-f", podname})
+ podrm.WaitWithDefaultTimeout()
+ Expect(podrm.ExitCode()).To(BeZero())
+
+ netrm := podmanTest.Podman([]string{"network", "rm", netName})
+ netrm.WaitWithDefaultTimeout()
+ Expect(netrm.ExitCode()).To(BeZero())
})
})
diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go
index 6c65a23e8..157b7d3d7 100644
--- a/test/e2e/run_test.go
+++ b/test/e2e/run_test.go
@@ -867,6 +867,14 @@ USER mail`
Expect(match).To(BeTrue())
})
+ It("podman run --pod new with hostname", func() {
+ hostname := "abc"
+ session := podmanTest.Podman([]string{"run", "--pod", "new:foobar", "--hostname", hostname, ALPINE, "cat", "/etc/hostname"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.OutputToString()).To(ContainSubstring(hostname))
+ })
+
It("podman run --rm should work", func() {
session := podmanTest.Podman([]string{"run", "--name", "test", "--rm", ALPINE, "ls"})
session.WaitWithDefaultTimeout()
diff --git a/test/system/005-info.bats b/test/system/005-info.bats
index c53ba8125..3f1efd364 100644
--- a/test/system/005-info.bats
+++ b/test/system/005-info.bats
@@ -3,8 +3,6 @@
load helpers
@test "podman info - basic test" {
- skip_if_remote "capitalization inconsistencies"
-
run_podman info
expected_keys="
@@ -28,8 +26,6 @@ runRoot:
}
@test "podman info - json" {
- skip_if_remote "capitalization inconsistencies"
-
run_podman info --format=json
expr_nvr="[a-z0-9-]\\\+-[a-z0-9.]\\\+-[a-z0-9]\\\+\."
diff --git a/test/system/010-images.bats b/test/system/010-images.bats
index 2b1845d72..7fd731ca0 100644
--- a/test/system/010-images.bats
+++ b/test/system/010-images.bats
@@ -75,8 +75,6 @@ Size | [0-9]\\\+
}
@test "podman images - filter" {
- skip_if_remote "podman commit -q is broken in podman-remote"
-
run_podman inspect --format '{{.ID}}' $IMAGE
iid=$output
diff --git a/test/system/015-help.bats b/test/system/015-help.bats
index 76d29d22c..4a3781012 100644
--- a/test/system/015-help.bats
+++ b/test/system/015-help.bats
@@ -178,6 +178,14 @@ function check_help() {
# Called with no args -- start with 'podman --help'. check_help() will
# recurse for any subcommands.
check_help
+
+ # Test for regression of #7273 (spurious "--remote" help on output)
+ for helpopt in help --help; do
+ run_podman $helpopt
+ is "${lines[0]}" "Manage pods, containers and images" \
+ "podman $helpopt: first line of output"
+ done
+
}
# vim: filetype=sh
diff --git a/test/system/030-run.bats b/test/system/030-run.bats
index 41863ba04..34afd5bae 100644
--- a/test/system/030-run.bats
+++ b/test/system/030-run.bats
@@ -63,7 +63,7 @@ echo $rand | 0 | $rand
# 'run --preserve-fds' passes a number of additional file descriptors into the container
@test "podman run --preserve-fds" {
- skip_if_remote
+ skip_if_remote "preserve-fds is meaningless over remote"
content=$(random_string 20)
echo "$content" > $PODMAN_TMPDIR/tempfile
@@ -150,8 +150,6 @@ echo $rand | 0 | $rand
# 'run --rmi' deletes the image in the end unless it's used by another container
@test "podman run --rmi" {
- skip_if_remote
-
# Name of a nonlocal image. It should be pulled in by the first 'run'
NONLOCAL_IMAGE=busybox
run_podman 1 image exists $NONLOCAL_IMAGE
diff --git a/test/system/060-mount.bats b/test/system/060-mount.bats
index 7570f3ac4..d98a3eeb1 100644
--- a/test/system/060-mount.bats
+++ b/test/system/060-mount.bats
@@ -6,7 +6,7 @@ load helpers
@test "podman mount - basic test" {
# Only works with root (FIXME: does it work with rootless + vfs?)
skip_if_rootless "mount does not work rootless"
- skip_if_remote
+ skip_if_remote "mounting remote is meaningless"
f_path=/tmp/tmpfile_$(random_string 8)
f_content=$(random_string 30)
diff --git a/test/system/075-exec.bats b/test/system/075-exec.bats
index 38c6c2312..5f71e2acb 100644
--- a/test/system/075-exec.bats
+++ b/test/system/075-exec.bats
@@ -39,7 +39,7 @@ load helpers
}
@test "podman exec - leak check" {
- skip_if_remote
+ skip_if_remote "test is meaningless over remote"
# Start a container in the background then run exec command
# three times and make sure no any exec pid hash file leak
@@ -61,7 +61,7 @@ load helpers
# Issue #4785 - piping to exec statement - fixed in #4818
# Issue #5046 - piping to exec truncates results (actually a conmon issue)
@test "podman exec - cat from stdin" {
- skip_if_remote
+ skip_if_remote "FIXME: pending #7360"
run_podman run -d $IMAGE sh -c 'while [ ! -e /stop ]; do sleep 0.1;done'
cid="$output"
diff --git a/test/system/120-load.bats b/test/system/120-load.bats
index 14dae4c8a..86b396c4a 100644
--- a/test/system/120-load.bats
+++ b/test/system/120-load.bats
@@ -27,13 +27,25 @@ verify_iid_and_name() {
}
@test "podman save to pipe and load" {
+ get_iid_and_name
+
# We can't use run_podman because that uses the BATS 'run' function
# which redirects stdout and stderr. Here we need to guarantee
# that podman's stdout is a pipe, not any other form of redirection
- $PODMAN save --format oci-archive $IMAGE | cat >$PODMAN_TMPDIR/test.tar
- [ $status -eq 0 ]
+ $PODMAN save --format oci-archive $IMAGE | cat >$archive
+ if [ "$status" -ne 0 ]; then
+ die "Command failed: podman save ... | cat"
+ fi
+
+ # Make sure we can reload it
+ # FIXME: when/if 7337 gets fixed, add a random tag instead of rmi'ing
+ # FIXME: when/if 7371 gets fixed, use verify_iid_and_name()
+ run_podman rmi $iid
+ run_podman load -i $archive
- run_podman load -i $PODMAN_TMPDIR/test.tar
+ # FIXME: cannot compare IID, see #7371
+ run_podman images -a --format '{{.Repository}}:{{.Tag}}'
+ is "$output" "$IMAGE" "image preserves name across save/load"
}
diff --git a/test/system/200-pod.bats b/test/system/200-pod.bats
index f3ec8a67c..7189d7e4b 100644
--- a/test/system/200-pod.bats
+++ b/test/system/200-pod.bats
@@ -96,9 +96,8 @@ function teardown() {
run_podman rm $cid1
# ...then, from pause container, find the image ID of the pause image...
- # FIXME: if #6283 gets implemented, use 'inspect --format ...'
- run_podman pod inspect $podname
- pause_cid=$(jq -r '.Containers[0].Id' <<<"$output")
+ run_podman pod inspect --format '{{(index .Containers 0).ID}}' $podname
+ pause_cid="$output"
run_podman container inspect --format '{{.Image}}' $pause_cid
pause_iid="$output"
diff --git a/test/system/250-systemd.bats b/test/system/250-systemd.bats
index b7035cdda..bbb5a10fb 100644
--- a/test/system/250-systemd.bats
+++ b/test/system/250-systemd.bats
@@ -18,7 +18,7 @@ fi
UNIT_FILE="$UNIT_DIR/$SERVICE_NAME.service"
function setup() {
- skip_if_remote
+ skip_if_remote "systemd tests are meaningless over remote"
basic_setup
}
diff --git a/test/system/260-sdnotify.bats b/test/system/260-sdnotify.bats
index 7be4be983..62d3c1497 100644
--- a/test/system/260-sdnotify.bats
+++ b/test/system/260-sdnotify.bats
@@ -10,7 +10,7 @@ _SOCAT_PID=
_SOCAT_LOG=
function setup() {
- skip_if_remote
+ skip_if_remote "systemd tests are meaningless over remote"
skip "FIXME FIXME FIXME, is this what's causing the CI hang???"
diff --git a/test/system/500-networking.bats b/test/system/500-networking.bats
index 234bc1187..0fae3dcd3 100644
--- a/test/system/500-networking.bats
+++ b/test/system/500-networking.bats
@@ -7,7 +7,7 @@ load helpers
# Copied from tsweeney's https://github.com/containers/podman/issues/4827
@test "podman networking: port on localhost" {
- skip_if_remote
+ skip_if_remote "FIXME: reevaluate this one after #7360 is fixed"
random_1=$(random_string 30)
random_2=$(random_string 30)
@@ -62,8 +62,6 @@ load helpers
# Issue #5466 - port-forwarding doesn't work with this option and -d
@test "podman networking: port with --userns=keep-id" {
- skip_if_remote
-
# FIXME: randomize port, and create second random host port
myport=54321
diff --git a/vendor/github.com/containers/image/v5/docker/docker_client.go b/vendor/github.com/containers/image/v5/docker/docker_client.go
index 9461bc91a..e4308def1 100644
--- a/vendor/github.com/containers/image/v5/docker/docker_client.go
+++ b/vendor/github.com/containers/image/v5/docker/docker_client.go
@@ -331,7 +331,6 @@ func SearchRegistry(ctx context.Context, sys *types.SystemContext, registry, ima
// Results holds the results returned by the /v1/search endpoint
Results []SearchResult `json:"results"`
}
- v2Res := &V2Results{}
v1Res := &V1Results{}
// Get credentials from authfile for the underlying hostname
@@ -388,31 +387,55 @@ func SearchRegistry(ctx context.Context, sys *types.SystemContext, registry, ima
}
logrus.Debugf("trying to talk to v2 search endpoint")
- resp, err := client.makeRequest(ctx, "GET", "/v2/_catalog", nil, nil, v2Auth, nil)
- if err != nil {
- logrus.Debugf("error getting search results from v2 endpoint %q: %v", registry, err)
- } else {
+ searchRes := []SearchResult{}
+ path := "/v2/_catalog"
+ for len(searchRes) < limit {
+ resp, err := client.makeRequest(ctx, "GET", path, nil, nil, v2Auth, nil)
+ if err != nil {
+ logrus.Debugf("error getting search results from v2 endpoint %q: %v", registry, err)
+ return nil, errors.Wrapf(err, "couldn't search registry %q", registry)
+ }
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
logrus.Errorf("error getting search results from v2 endpoint %q: %v", registry, httpResponseToError(resp, ""))
- } else {
- if err := json.NewDecoder(resp.Body).Decode(v2Res); err != nil {
- return nil, err
+ return nil, errors.Wrapf(err, "couldn't search registry %q", registry)
+ }
+ v2Res := &V2Results{}
+ if err := json.NewDecoder(resp.Body).Decode(v2Res); err != nil {
+ return nil, err
+ }
+
+ for _, repo := range v2Res.Repositories {
+ if len(searchRes) == limit {
+ break
}
- searchRes := []SearchResult{}
- for _, repo := range v2Res.Repositories {
- if strings.Contains(repo, image) {
- res := SearchResult{
- Name: repo,
- }
- searchRes = append(searchRes, res)
+ if strings.Contains(repo, image) {
+ res := SearchResult{
+ Name: repo,
}
+ searchRes = append(searchRes, res)
}
- return searchRes, nil
}
- }
- return nil, errors.Wrapf(err, "couldn't search registry %q", registry)
+ link := resp.Header.Get("Link")
+ if link == "" {
+ break
+ }
+ linkURLStr := strings.Trim(strings.Split(link, ";")[0], "<>")
+ linkURL, err := url.Parse(linkURLStr)
+ if err != nil {
+ return searchRes, err
+ }
+
+ // can be relative or absolute, but we only want the path (and I
+ // guess we're in trouble if it forwards to a new place...)
+ path = linkURL.Path
+ if linkURL.RawQuery != "" {
+ path += "?"
+ path += linkURL.RawQuery
+ }
+ }
+ return searchRes, nil
}
// makeRequest creates and executes a http.Request with the specified parameters, adding authentication and TLS options for the Docker client.
diff --git a/vendor/github.com/containers/image/v5/version/version.go b/vendor/github.com/containers/image/v5/version/version.go
index 114bce387..2f56effae 100644
--- a/vendor/github.com/containers/image/v5/version/version.go
+++ b/vendor/github.com/containers/image/v5/version/version.go
@@ -8,7 +8,7 @@ const (
// VersionMinor is for functionality in a backwards-compatible manner
VersionMinor = 5
// VersionPatch is for backwards-compatible bug fixes
- VersionPatch = 1
+ VersionPatch = 2
// VersionDev indicates development branch. Releases will be empty string.
VersionDev = ""
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 0ab37e30c..c6e098f58 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -95,7 +95,7 @@ github.com/containers/common/pkg/sysinfo
github.com/containers/common/version
# github.com/containers/conmon v2.0.19+incompatible
github.com/containers/conmon/runner/config
-# github.com/containers/image/v5 v5.5.1
+# github.com/containers/image/v5 v5.5.2
github.com/containers/image/v5/copy
github.com/containers/image/v5/directory
github.com/containers/image/v5/directory/explicitfilepath