aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/ISSUE_TEMPLATE.md17
-rw-r--r--Makefile2
-rw-r--r--README.md47
-rw-r--r--cmd/podman/main.go11
-rw-r--r--cmd/podman/search.go5
-rw-r--r--docs/podman-search.1.md27
-rw-r--r--libpod/image/pull.go9
-rw-r--r--pkg/secrets/secrets.go4
-rw-r--r--pkg/spec/createconfig.go6
-rw-r--r--pkg/spec/spec.go12
-rw-r--r--pkg/spec/spec_test.go2
-rw-r--r--test/e2e/search_test.go13
-rw-r--r--troubleshooting.md15
-rw-r--r--vendor.conf2
-rw-r--r--vendor/github.com/containers/image/docker/docker_client.go87
-rw-r--r--vendor/github.com/containers/image/docker/docker_image.go2
-rw-r--r--vendor/github.com/containers/image/docker/docker_image_dest.go12
-rw-r--r--vendor/github.com/containers/image/docker/docker_image_src.go10
-rw-r--r--vendor/github.com/containers/image/ostree/ostree_dest.go4
-rw-r--r--version/version.go3
20 files changed, 207 insertions, 83 deletions
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index f4a25be88..656d23d67 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -5,6 +5,13 @@ BUG REPORT INFORMATION
Use the commands below to provide key information from your environment:
You do NOT have to include this information if this is a FEATURE REQUEST
+**NOTE** A large number of issues reported against Podman are often found to already be fixed
+in more current versions of the project. Before reporting an issue, please verify the
+version you are running with `podman version` and compare it to the latest release
+documented on the top of Podman's [README.md](../README.md). If they differ, please
+update your version of Podman to the latest possible and retry your command before creating
+an issue.
+
If you are filing a bug against `podman build`, please instead file a bug
against Buildah (https://github.com/projectatomic/buildah/issues). Podman build
executes Buildah to perform container builds, and as such the Buildah
@@ -13,11 +20,11 @@ maintainers are best equipped to handle these bugs.
**Is this a BUG REPORT or FEATURE REQUEST?**:
-> Uncomment only one, leave it on its own line:
->
-> /kind bug
->
-> /kind feature
+[//]: # Uncomment only one, leave it on its own line:
+
+[//]: # **kind bug**
+
+[//]: # **kind feature**
**Description**
diff --git a/Makefile b/Makefile
index 7a529f4d5..47baaf7d2 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
GO ?= go
DESTDIR ?= /
-EPOCH_TEST_COMMIT ?= 6ffce631db6e01f66b09cb0e894600182caa872c
+EPOCH_TEST_COMMIT ?= 0cb0849c722f3e1c41d2005488cc2951b8d16f53
HEAD ?= HEAD
CHANGELOG_BASE ?= HEAD~
CHANGELOG_TARGET ?= HEAD
diff --git a/README.md b/README.md
index 0f31c24a9..bd4f2c0d5 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,7 @@
![PODMAN logo](logo/podman-logo-source.svg)
# libpod - library for running OCI-based containers in Pods
+### Latest Version: 0.9.1
### Status: Active Development
## What is the scope of this project?
@@ -63,12 +64,44 @@ Release notes for recent Podman versions
**[Contributing](CONTRIBUTING.md)**
Information about contributing to this project.
-### Current Roadmap
+## Current Roadmap
-1. Varlink API for Podman
+1. Python frontend for Varlink API
1. Integrate libpod into CRI-O to replace its existing container management backend
-1. Pod commands for Podman
-1. Rootless containers
-1. Support for cleaning up containers via post-run hooks
-
-[spec-hooks]: https://github.com/opencontainers/runtime-spec/blob/v1.0.1/config.md#posix-platform-hooks
+1. Further work on the podman pod command
+1. Further improvements on rootless containers
+1. In-memory locking to replace file locks
+
+[spec-hooks]: https://github.com/opencontainers/runtime-spec/blob/v2.0.1/config.md#posix-platform-hooks
+
+## Buildah and Podman relationship
+
+Buildah and Podman are two complementary Open-source projects that are available on
+most Linux platforms and both projects reside at [GitHub.com](https://github.com)
+with Buildah [here](https://github.com/projectatomic/buildah) and
+Podman [here](https://github.com/containers/libpod). Both Buildah and Podman are
+command line tools that work on OCI images and containers. The two projects
+differentiate in their specialization.
+
+Buildah specializes in building OCI images. Buildah's commands replicate all
+of the commands that are found in a Dockerfile. Buildah’s goal is also to
+provide a lower level coreutils interface to build images, allowing people to build
+containers without requiring a Dockerfile. The intent with Buildah is to allow other
+scripting languages to build container images, without requiring a daemon.
+
+Podman specializes in all of the commands and functions that help you to maintain and modify
+OCI images, such as pulling and tagging. It also allows you to create, run, and maintain those containers
+created from those images.
+
+A major difference between Podman and Buildah is their concept of a container. Podman
+allows users to create "traditional containers" where the intent of these containers is
+to be long lived. While Buildah containers are really just created to allow content
+to be added back to the container image. An easy way to think of it is the
+`buildah run` command emulates the RUN command in a Dockerfile while the `podman run`
+command emulates the `docker run` command in functionality. Because of this and their underlying
+storage differences, you can not see Podman containers from within Buildah or vice versa.
+
+In short Buildah is an efficient way to create OCI images while Podman allows
+you to manage and maintain those images and containers in a production environment using
+familiar container cli commands. For more details, see the
+[Container Tools Guide](https://github.com/projectatomic/buildah/tree/master/docs/containertools).
diff --git a/cmd/podman/main.go b/cmd/podman/main.go
index 8d470e10d..a532bc26e 100644
--- a/cmd/podman/main.go
+++ b/cmd/podman/main.go
@@ -138,6 +138,17 @@ func main() {
logrus.SetLevel(level)
}
+ // Only if not rootless, set rlimits for open files.
+ // We open numerous FDs for ports opened
+ if !rootless.IsRootless() {
+ rlimits := new(syscall.Rlimit)
+ rlimits.Cur = 1048576
+ rlimits.Max = 1048576
+ if err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, rlimits); err != nil {
+ return errors.Wrapf(err, "error setting new rlimits")
+ }
+ }
+
if logLevel == "debug" {
debug = true
diff --git a/cmd/podman/search.go b/cmd/podman/search.go
index 009ff8ba9..f64b822fc 100644
--- a/cmd/podman/search.go
+++ b/cmd/podman/search.go
@@ -345,6 +345,11 @@ func matchesOfficialFilter(filter searchFilterParams, result docker.SearchResult
}
func getRegistry(image string) (string, error) {
+ // It is possible to only have the registry name in the format "myregistry/"
+ // if so, just trim the "/" from the end and return the registry name
+ if strings.HasSuffix(image, "/") {
+ return strings.TrimSuffix(image, "/"), nil
+ }
imgRef, err := reference.Parse(image)
if err != nil {
return "", err
diff --git a/docs/podman-search.1.md b/docs/podman-search.1.md
index 9cc9e1e6b..429c3c5ad 100644
--- a/docs/podman-search.1.md
+++ b/docs/podman-search.1.md
@@ -10,10 +10,12 @@ podman\-search - Search a registry for an image
**podman search** searches a registry or a list of registries for a matching image.
The user can specify which registry to search by prefixing the registry in the search term
(example **registry.fedoraproject.org/fedora**), default is the registries in the
-**registires.search** table in the config file - **/etc/containers/registries.conf**.
+**registries.search** table in the config file - **/etc/containers/registries.conf**.
The number of results can be limited using the **--limit** flag. If more than one registry
is being searched, the limit will be applied to each registry. The output can be filtered
-using the **--filter** flag.
+using the **--filter** flag. To get all available images in a registry without a specific
+search term, the user can just enter the registry name with a trailing "/" (example **registry.fedoraproject.org/**).
+Note, searching without a search term will only work for registries that implement the v2 API.
**podman [GLOBAL OPTIONS]**
@@ -116,6 +118,27 @@ INDEX NAME
fedoraproject.org fedoraproject.org/fedora
fedoraproject.org fedoraproject.org/fedora-minimal
```
+
+```
+$ podman search registry.fedoraproject.org/
+INDEX NAME DESCRIPTION STARS OFFICIAL AUTOMATED
+fedoraproject.org registry.fedoraproject.org/f25/cockpit 0
+fedoraproject.org registry.fedoraproject.org/f25/container-engine 0
+fedoraproject.org registry.fedoraproject.org/f25/docker 0
+fedoraproject.org registry.fedoraproject.org/f25/etcd 0
+fedoraproject.org registry.fedoraproject.org/f25/flannel 0
+fedoraproject.org registry.fedoraproject.org/f25/httpd 0
+fedoraproject.org registry.fedoraproject.org/f25/kubernetes-apiserver 0
+fedoraproject.org registry.fedoraproject.org/f25/kubernetes-controller-manager 0
+fedoraproject.org registry.fedoraproject.org/f25/kubernetes-kubelet 0
+fedoraproject.org registry.fedoraproject.org/f25/kubernetes-master 0
+fedoraproject.org registry.fedoraproject.org/f25/kubernetes-node 0
+fedoraproject.org registry.fedoraproject.org/f25/kubernetes-proxy 0
+fedoraproject.org registry.fedoraproject.org/f25/kubernetes-scheduler 0
+fedoraproject.org registry.fedoraproject.org/f25/mariadb 0
+```
+Note: This works only with registries that implement the v2 API. If tried with a v1 registry an error will be returned.
+
## FILES
**registries.conf** (`/etc/containers/registries.conf`)
diff --git a/libpod/image/pull.go b/libpod/image/pull.go
index ce3e8e73e..9eac2b988 100644
--- a/libpod/image/pull.go
+++ b/libpod/image/pull.go
@@ -20,6 +20,7 @@ import (
"github.com/containers/image/types"
"github.com/containers/libpod/pkg/registries"
"github.com/containers/libpod/pkg/util"
+ multierror "github.com/hashicorp/go-multierror"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
@@ -234,6 +235,7 @@ func (ir *Runtime) doPullImage(ctx context.Context, sc *types.SystemContext, goa
return nil, err
}
var images []string
+ var pullErrors *multierror.Error
for _, imageInfo := range goal.refPairs {
copyOptions := getCopyOptions(sc, writer, dockerOptions, nil, signingOptions, "", nil)
if imageInfo.srcRef.Transport().Name() == DockerTransport {
@@ -254,6 +256,7 @@ func (ir *Runtime) doPullImage(ctx context.Context, sc *types.SystemContext, goa
io.WriteString(writer, fmt.Sprintf("Trying to pull %s...", imageInfo.image))
}
if err = cp.Image(ctx, policyContext, imageInfo.dstRef, imageInfo.srcRef, copyOptions); err != nil {
+ pullErrors = multierror.Append(pullErrors, err)
logrus.Debugf("Error pulling image ref %s: %v", imageInfo.srcRef.StringWithinTransport(), err)
if writer != nil {
io.WriteString(writer, "Failed\n")
@@ -273,10 +276,12 @@ func (ir *Runtime) doPullImage(ctx context.Context, sc *types.SystemContext, goa
}
// If the image passed in was fully-qualified, we will have 1 refpair. Bc the image is fq'd, we dont need to yap about registries.
if !goal.usedSearchRegistries {
+ if pullErrors != nil && len(pullErrors.Errors) > 0 { // this should always be true
+ return nil, errors.Wrap(pullErrors.Errors[0], "unable to pull image")
+ }
return nil, errors.Errorf("unable to pull image, or you do not have pull access")
}
- return nil, errors.Errorf("unable to find image on registries defined in %s, or you do not have pull access", registryPath)
-
+ return nil, pullErrors
}
return images, nil
}
diff --git a/pkg/secrets/secrets.go b/pkg/secrets/secrets.go
index be5642eba..7208f53b7 100644
--- a/pkg/secrets/secrets.go
+++ b/pkg/secrets/secrets.go
@@ -243,7 +243,7 @@ func addSecretsFromMountsFile(filePath, mountLabel, containerWorkingDir, mountPr
Source: filepath.Join(mountPrefix, ctrDir),
Destination: ctrDir,
Type: "bind",
- Options: []string{"bind", "private"},
+ Options: []string{"bind", "rprivate"},
}
mounts = append(mounts, m)
@@ -278,7 +278,7 @@ func addFIPSModeSecret(mounts *[]rspec.Mount, containerWorkingDir string) error
Source: ctrDirOnHost,
Destination: secretsDir,
Type: "bind",
- Options: []string{"bind", "private"},
+ Options: []string{"bind", "rprivate"},
}
*mounts = append(*mounts, m)
}
diff --git a/pkg/spec/createconfig.go b/pkg/spec/createconfig.go
index 3cca345b4..a441b4019 100644
--- a/pkg/spec/createconfig.go
+++ b/pkg/spec/createconfig.go
@@ -189,7 +189,7 @@ func (c *CreateConfig) GetVolumeMounts(specMounts []spec.Mount) ([]spec.Mount, e
}
}
if rootProp == "" {
- options = append(options, "private")
+ options = append(options, "rprivate")
}
m = append(m, spec.Mount{
@@ -214,7 +214,7 @@ func (c *CreateConfig) GetVolumeMounts(specMounts []spec.Mount) ([]spec.Mount, e
Destination: vol,
Type: string(TypeTmpfs),
Source: string(TypeTmpfs),
- Options: []string{"private", "rw", "noexec", "nosuid", "nodev", "tmpcopyup"},
+ Options: []string{"rprivate", "rw", "noexec", "nosuid", "nodev", "tmpcopyup"},
}
m = append(m, mount)
}
@@ -272,7 +272,7 @@ func (c *CreateConfig) GetTmpfsMounts() []spec.Mount {
var m []spec.Mount
for _, i := range c.Tmpfs {
// Default options if nothing passed
- options := []string{"private", "rw", "noexec", "nosuid", "nodev", "size=65536k"}
+ options := []string{"rprivate", "rw", "noexec", "nosuid", "nodev", "size=65536k"}
spliti := strings.Split(i, ":")
destPath := spliti[0]
if len(spliti) > 1 {
diff --git a/pkg/spec/spec.go b/pkg/spec/spec.go
index 77dbf8b42..cc3501e1e 100644
--- a/pkg/spec/spec.go
+++ b/pkg/spec/spec.go
@@ -43,7 +43,7 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
Destination: "/sys",
Type: "sysfs",
Source: "sysfs",
- Options: []string{"private", "nosuid", "noexec", "nodev", "rw"},
+ Options: []string{"rprivate", "nosuid", "noexec", "nodev", "rw"},
}
g.AddMount(sysMnt)
} else if !canMountSys {
@@ -57,7 +57,7 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
Destination: "/sys",
Type: "bind",
Source: "/sys",
- Options: []string{"nosuid", "noexec", "nodev", r, "rbind"},
+ Options: []string{"rprivate", "nosuid", "noexec", "nodev", r, "rbind"},
}
g.AddMount(sysMnt)
}
@@ -67,7 +67,7 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
Destination: "/dev/pts",
Type: "devpts",
Source: "devpts",
- Options: []string{"private", "nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620"},
+ Options: []string{"rprivate", "nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620"},
}
g.AddMount(devPts)
}
@@ -97,7 +97,7 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
Destination: "/sys/fs/cgroup",
Type: "cgroup",
Source: "cgroup",
- Options: []string{"private", "nosuid", "noexec", "nodev", "relatime", cgroupPerm},
+ Options: []string{"rprivate", "nosuid", "noexec", "nodev", "relatime", cgroupPerm},
}
g.AddMount(cgroupMnt)
}
@@ -231,7 +231,7 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
}
for _, i := range config.Tmpfs {
// Default options if nothing passed
- options := []string{"rw", "private", "noexec", "nosuid", "nodev", "size=65536k"}
+ options := []string{"rw", "rprivate", "noexec", "nosuid", "nodev", "size=65536k"}
spliti := strings.SplitN(i, ":", 2)
if len(spliti) > 1 {
if _, _, err := mount.ParseTmpfsOptions(spliti[1]); err != nil {
@@ -385,7 +385,7 @@ func setupSystemd(config *CreateConfig, g *generate.Generator) error {
if err != nil {
return err
}
- options := []string{"rw", "private", "noexec", "nosuid", "nodev"}
+ options := []string{"rw", "rprivate", "noexec", "nosuid", "nodev"}
for _, dest := range []string{"/run", "/run/lock", "/sys/fs/cgroup/systemd"} {
if libpod.MountExists(mounts, dest) {
continue
diff --git a/pkg/spec/spec_test.go b/pkg/spec/spec_test.go
index de3605068..c037bf69e 100644
--- a/pkg/spec/spec_test.go
+++ b/pkg/spec/spec_test.go
@@ -13,7 +13,7 @@ func TestCreateConfig_GetVolumeMounts(t *testing.T) {
Destination: "/foobar",
Type: "bind",
Source: "foobar",
- Options: []string{"ro", "rbind", "private"},
+ Options: []string{"ro", "rbind", "rprivate"},
}
config := CreateConfig{
Volumes: []string{"foobar:/foobar:ro"},
diff --git a/test/e2e/search_test.go b/test/e2e/search_test.go
index 7b9612a35..1f06bf4a1 100644
--- a/test/e2e/search_test.go
+++ b/test/e2e/search_test.go
@@ -60,10 +60,10 @@ var _ = Describe("Podman search", func() {
})
It("podman search single registry flag", func() {
- search := podmanTest.Podman([]string{"search", "registry.fedoraproject.org/fedora-minimal"})
+ search := podmanTest.Podman([]string{"search", "registry.fedoraproject.org/fedora"})
search.WaitWithDefaultTimeout()
Expect(search.ExitCode()).To(Equal(0))
- Expect(search.LineInOutputContains("fedoraproject.org/fedora-minimal")).To(BeTrue())
+ Expect(search.LineInOutputContains("fedoraproject.org/fedora")).To(BeTrue())
})
It("podman search format flag", func() {
@@ -84,7 +84,7 @@ var _ = Describe("Podman search", func() {
})
It("podman search limit flag", func() {
- search := podmanTest.Podman([]string{"search", "--limit", "3", "alpine"})
+ search := podmanTest.Podman([]string{"search", "--limit", "3", "docker.io/alpine"})
search.WaitWithDefaultTimeout()
Expect(search.ExitCode()).To(Equal(0))
Expect(len(search.OutputToStringArray())).To(Equal(4))
@@ -120,6 +120,13 @@ var _ = Describe("Podman search", func() {
}
})
+ It("podman search v2 registry with empty query", func() {
+ search := podmanTest.Podman([]string{"search", "registry.fedoraproject.org/"})
+ search.WaitWithDefaultTimeout()
+ Expect(search.ExitCode()).To(Equal(0))
+ Expect(len(search.OutputToStringArray())).To(BeNumerically(">=", 1))
+ })
+
It("podman search attempts HTTP if tls-verify flag is set false", func() {
podmanTest.RestoreArtifact(registry)
fakereg := podmanTest.Podman([]string{"run", "-d", "--name", "registry", "-p", "5000:5000", registry, "/entrypoint.sh", "/etc/docker/registry/config.yml"})
diff --git a/troubleshooting.md b/troubleshooting.md
index d0d84f7cc..db36d1bb8 100644
--- a/troubleshooting.md
+++ b/troubleshooting.md
@@ -5,7 +5,18 @@
## A list of common issues and solutions for Podman
---
-### 1) No such image or Bare keys cannot contain ':'
+### 1) Variety of issues - Validate Version
+
+A large number of issues reported against Podman are often found to already be fixed
+in more current versions of the project. Before reporting an issue, please verify the
+version you are running with `podman version` and compare it to the lastest release
+documented on the top of Podman's [README.md](README.md).
+
+If they differ, please update your version of PODMAN to the latest possible
+and retry your command before reporting the issue.
+
+---
+### 2) No such image or Bare keys cannot contain ':'
When doing a `podman pull` or `podman build` command and a "common" image can not be pulled,
it is likely that the `/etc/containers/registries.conf` file is either not installed or possibly
@@ -33,7 +44,7 @@ error pulling image "fedora": unable to pull fedora: error getting default regis
* i.e. `registries = ['registry.fedoraproject.org', 'quay.io', 'registry.access.redhat.com']`
---
-### 2) http: server gave HTTP response to HTTPS client
+### 3) http: server gave HTTP response to HTTPS client
When doing a Podman command such as `build`, `commit`, `pull`, or `push` to a registry,
tls verification is turned on by default. If authentication is not used with
diff --git a/vendor.conf b/vendor.conf
index 390615dfa..c21cb4b8e 100644
--- a/vendor.conf
+++ b/vendor.conf
@@ -10,7 +10,7 @@ github.com/containerd/cgroups 58556f5ad8448d99a6f7bea69ea4bdb7747cfeb0
github.com/containerd/continuity master
github.com/containernetworking/cni v0.7.0-alpha1
github.com/containernetworking/plugins 1562a1e60ed101aacc5e08ed9dbeba8e9f3d4ec1
-github.com/containers/image 5df44e095ed826fbe2beeaabb329c749d7d6c3b6
+github.com/containers/image d8b5cf2b804a48489e5203d51254ef576794049d
github.com/containers/storage 243c4cd616afdf06b4a975f18c4db083d26b1641
github.com/containers/psgo 5dde6da0bc8831b35243a847625bcf18183bd1ee
github.com/coreos/go-systemd v14
diff --git a/vendor/github.com/containers/image/docker/docker_client.go b/vendor/github.com/containers/image/docker/docker_client.go
index cae73a6cd..4fb10c395 100644
--- a/vendor/github.com/containers/image/docker/docker_client.go
+++ b/vendor/github.com/containers/image/docker/docker_client.go
@@ -100,6 +100,19 @@ type authScope struct {
actions string
}
+// sendAuth determines whether we need authentication for v2 or v1 endpoint.
+type sendAuth int
+
+const (
+ // v2 endpoint with authentication.
+ v2Auth sendAuth = iota
+ // v1 endpoint with authentication.
+ // TODO: Get v1Auth working
+ // v1Auth
+ // no authentication, works for both v1 and v2.
+ noAuth
+)
+
func newBearerTokenFromJSONBlob(blob []byte) (*bearerToken, error) {
token := new(bearerToken)
if err := json.Unmarshal(blob, &token); err != nil {
@@ -234,7 +247,7 @@ func CheckAuth(ctx context.Context, sys *types.SystemContext, username, password
return errors.Wrapf(err, "error creating new docker client")
}
- resp, err := newLoginClient.makeRequest(ctx, "GET", "/v2/", nil, nil)
+ resp, err := newLoginClient.makeRequest(ctx, "GET", "/v2/", nil, nil, v2Auth)
if err != nil {
return err
}
@@ -297,14 +310,43 @@ func SearchRegistry(ctx context.Context, sys *types.SystemContext, registry, ima
return nil, errors.Wrapf(err, "error creating new docker client")
}
+ // Only try the v1 search endpoint if the search query is not empty. If it is
+ // empty skip to the v2 endpoint.
+ if image != "" {
+ // set up the query values for the v1 endpoint
+ u := url.URL{
+ Path: "/v1/search",
+ }
+ q := u.Query()
+ q.Set("q", image)
+ q.Set("n", strconv.Itoa(limit))
+ u.RawQuery = q.Encode()
+
+ logrus.Debugf("trying to talk to v1 search endpoint\n")
+ resp, err := client.makeRequest(ctx, "GET", u.String(), nil, nil, noAuth)
+ if err != nil {
+ logrus.Debugf("error getting search results from v1 endpoint %q: %v", registry, err)
+ } else {
+ defer resp.Body.Close()
+ if resp.StatusCode != http.StatusOK {
+ logrus.Debugf("error getting search results from v1 endpoint %q, status code %d", registry, resp.StatusCode)
+ } else {
+ if err := json.NewDecoder(resp.Body).Decode(v1Res); err != nil {
+ return nil, err
+ }
+ return v1Res.Results, nil
+ }
+ }
+ }
+
logrus.Debugf("trying to talk to v2 search endpoint\n")
- resp, err := client.makeRequest(ctx, "GET", "/v2/_catalog", nil, nil)
+ resp, err := client.makeRequest(ctx, "GET", "/v2/_catalog", nil, nil, v2Auth)
if err != nil {
logrus.Debugf("error getting search results from v2 endpoint %q: %v", registry, err)
} else {
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
- logrus.Debugf("error getting search results from v2 endpoint %q, status code %q", registry, resp.StatusCode)
+ logrus.Errorf("error getting search results from v2 endpoint %q, status code %d", registry, resp.StatusCode)
} else {
if err := json.NewDecoder(resp.Body).Decode(v2Res); err != nil {
return nil, err
@@ -322,50 +364,25 @@ func SearchRegistry(ctx context.Context, sys *types.SystemContext, registry, ima
}
}
- // set up the query values for the v1 endpoint
- u := url.URL{
- Path: "/v1/search",
- }
- q := u.Query()
- q.Set("q", image)
- q.Set("n", strconv.Itoa(limit))
- u.RawQuery = q.Encode()
-
- logrus.Debugf("trying to talk to v1 search endpoint\n")
- resp, err = client.makeRequest(ctx, "GET", u.String(), nil, nil)
- if err != nil {
- logrus.Debugf("error getting search results from v1 endpoint %q: %v", registry, err)
- } else {
- defer resp.Body.Close()
- if resp.StatusCode != http.StatusOK {
- logrus.Debugf("error getting search results from v1 endpoint %q, status code %q", registry, resp.StatusCode)
- } else {
- if err := json.NewDecoder(resp.Body).Decode(v1Res); err != nil {
- return nil, err
- }
- return v1Res.Results, nil
- }
- }
-
return nil, errors.Wrapf(err, "couldn't search registry %q", registry)
}
// makeRequest creates and executes a http.Request with the specified parameters, adding authentication and TLS options for the Docker client.
// The host name and schema is taken from the client or autodetected, and the path is relative to it, i.e. the path usually starts with /v2/.
-func (c *dockerClient) makeRequest(ctx context.Context, method, path string, headers map[string][]string, stream io.Reader) (*http.Response, error) {
+func (c *dockerClient) makeRequest(ctx context.Context, method, path string, headers map[string][]string, stream io.Reader, auth sendAuth) (*http.Response, error) {
if err := c.detectProperties(ctx); err != nil {
return nil, err
}
url := fmt.Sprintf("%s://%s%s", c.scheme, c.registry, path)
- return c.makeRequestToResolvedURL(ctx, method, url, headers, stream, -1, true)
+ return c.makeRequestToResolvedURL(ctx, method, url, headers, stream, -1, auth)
}
// makeRequestToResolvedURL creates and executes a http.Request with the specified parameters, adding authentication and TLS options for the Docker client.
// streamLen, if not -1, specifies the length of the data expected on stream.
// makeRequest should generally be preferred.
// TODO(runcom): too many arguments here, use a struct
-func (c *dockerClient) makeRequestToResolvedURL(ctx context.Context, method, url string, headers map[string][]string, stream io.Reader, streamLen int64, sendAuth bool) (*http.Response, error) {
+func (c *dockerClient) makeRequestToResolvedURL(ctx context.Context, method, url string, headers map[string][]string, stream io.Reader, streamLen int64, auth sendAuth) (*http.Response, error) {
req, err := http.NewRequest(method, url, stream)
if err != nil {
return nil, err
@@ -383,7 +400,7 @@ func (c *dockerClient) makeRequestToResolvedURL(ctx context.Context, method, url
if c.sys != nil && c.sys.DockerRegistryUserAgent != "" {
req.Header.Add("User-Agent", c.sys.DockerRegistryUserAgent)
}
- if sendAuth {
+ if auth == v2Auth {
if err := c.setupRequestAuth(req); err != nil {
return nil, err
}
@@ -497,7 +514,7 @@ func (c *dockerClient) detectProperties(ctx context.Context) error {
ping := func(scheme string) error {
url := fmt.Sprintf(resolvedPingV2URL, scheme, c.registry)
- resp, err := c.makeRequestToResolvedURL(ctx, "GET", url, nil, nil, -1, true)
+ resp, err := c.makeRequestToResolvedURL(ctx, "GET", url, nil, nil, -1, noAuth)
if err != nil {
logrus.Debugf("Ping %s err %#v", url, err)
return err
@@ -524,7 +541,7 @@ func (c *dockerClient) detectProperties(ctx context.Context) error {
// best effort to understand if we're talking to a V1 registry
pingV1 := func(scheme string) bool {
url := fmt.Sprintf(resolvedPingV1URL, scheme, c.registry)
- resp, err := c.makeRequestToResolvedURL(ctx, "GET", url, nil, nil, -1, true)
+ resp, err := c.makeRequestToResolvedURL(ctx, "GET", url, nil, nil, -1, noAuth)
logrus.Debugf("Ping %s err %#v", url, err)
if err != nil {
return false
@@ -551,7 +568,7 @@ func (c *dockerClient) detectProperties(ctx context.Context) error {
// using the original data structures.
func (c *dockerClient) getExtensionsSignatures(ctx context.Context, ref dockerReference, manifestDigest digest.Digest) (*extensionSignatureList, error) {
path := fmt.Sprintf(extensionsSignaturePath, reference.Path(ref.ref), manifestDigest)
- res, err := c.makeRequest(ctx, "GET", path, nil, nil)
+ res, err := c.makeRequest(ctx, "GET", path, nil, nil, v2Auth)
if err != nil {
return nil, err
}
diff --git a/vendor/github.com/containers/image/docker/docker_image.go b/vendor/github.com/containers/image/docker/docker_image.go
index 010791241..a1a115080 100644
--- a/vendor/github.com/containers/image/docker/docker_image.go
+++ b/vendor/github.com/containers/image/docker/docker_image.go
@@ -66,7 +66,7 @@ func GetRepositoryTags(ctx context.Context, sys *types.SystemContext, ref types.
tags := make([]string, 0)
for {
- res, err := client.makeRequest(ctx, "GET", path, nil, nil)
+ res, err := client.makeRequest(ctx, "GET", path, nil, nil, v2Auth)
if err != nil {
return nil, err
}
diff --git a/vendor/github.com/containers/image/docker/docker_image_dest.go b/vendor/github.com/containers/image/docker/docker_image_dest.go
index 85d568995..94763d026 100644
--- a/vendor/github.com/containers/image/docker/docker_image_dest.go
+++ b/vendor/github.com/containers/image/docker/docker_image_dest.go
@@ -130,7 +130,7 @@ func (d *dockerImageDestination) PutBlob(ctx context.Context, stream io.Reader,
// FIXME? Chunked upload, progress reporting, etc.
uploadPath := fmt.Sprintf(blobUploadPath, reference.Path(d.ref.ref))
logrus.Debugf("Uploading %s", uploadPath)
- res, err := d.c.makeRequest(ctx, "POST", uploadPath, nil, nil)
+ res, err := d.c.makeRequest(ctx, "POST", uploadPath, nil, nil, v2Auth)
if err != nil {
return types.BlobInfo{}, err
}
@@ -147,7 +147,7 @@ func (d *dockerImageDestination) PutBlob(ctx context.Context, stream io.Reader,
digester := digest.Canonical.Digester()
sizeCounter := &sizeCounter{}
tee := io.TeeReader(stream, io.MultiWriter(digester.Hash(), sizeCounter))
- res, err = d.c.makeRequestToResolvedURL(ctx, "PATCH", uploadLocation.String(), map[string][]string{"Content-Type": {"application/octet-stream"}}, tee, inputInfo.Size, true)
+ res, err = d.c.makeRequestToResolvedURL(ctx, "PATCH", uploadLocation.String(), map[string][]string{"Content-Type": {"application/octet-stream"}}, tee, inputInfo.Size, v2Auth)
if err != nil {
logrus.Debugf("Error uploading layer chunked, response %#v", res)
return types.BlobInfo{}, err
@@ -166,7 +166,7 @@ func (d *dockerImageDestination) PutBlob(ctx context.Context, stream io.Reader,
// TODO: check inputInfo.Digest == computedDigest https://github.com/containers/image/pull/70#discussion_r77646717
locationQuery.Set("digest", computedDigest.String())
uploadLocation.RawQuery = locationQuery.Encode()
- res, err = d.c.makeRequestToResolvedURL(ctx, "PUT", uploadLocation.String(), map[string][]string{"Content-Type": {"application/octet-stream"}}, nil, -1, true)
+ res, err = d.c.makeRequestToResolvedURL(ctx, "PUT", uploadLocation.String(), map[string][]string{"Content-Type": {"application/octet-stream"}}, nil, -1, v2Auth)
if err != nil {
return types.BlobInfo{}, err
}
@@ -191,7 +191,7 @@ func (d *dockerImageDestination) HasBlob(ctx context.Context, info types.BlobInf
checkPath := fmt.Sprintf(blobsPath, reference.Path(d.ref.ref), info.Digest.String())
logrus.Debugf("Checking %s", checkPath)
- res, err := d.c.makeRequest(ctx, "HEAD", checkPath, nil, nil)
+ res, err := d.c.makeRequest(ctx, "HEAD", checkPath, nil, nil, v2Auth)
if err != nil {
return false, -1, err
}
@@ -237,7 +237,7 @@ func (d *dockerImageDestination) PutManifest(ctx context.Context, m []byte) erro
if mimeType != "" {
headers["Content-Type"] = []string{mimeType}
}
- res, err := d.c.makeRequest(ctx, "PUT", path, headers, bytes.NewReader(m))
+ res, err := d.c.makeRequest(ctx, "PUT", path, headers, bytes.NewReader(m), v2Auth)
if err != nil {
return err
}
@@ -442,7 +442,7 @@ sigExists:
}
path := fmt.Sprintf(extensionsSignaturePath, reference.Path(d.ref.ref), d.manifestDigest.String())
- res, err := d.c.makeRequest(ctx, "PUT", path, nil, bytes.NewReader(body))
+ res, err := d.c.makeRequest(ctx, "PUT", path, nil, bytes.NewReader(body), v2Auth)
if err != nil {
return err
}
diff --git a/vendor/github.com/containers/image/docker/docker_image_src.go b/vendor/github.com/containers/image/docker/docker_image_src.go
index 46145dff6..3ff826aaa 100644
--- a/vendor/github.com/containers/image/docker/docker_image_src.go
+++ b/vendor/github.com/containers/image/docker/docker_image_src.go
@@ -89,7 +89,7 @@ func (s *dockerImageSource) fetchManifest(ctx context.Context, tagOrDigest strin
path := fmt.Sprintf(manifestPath, reference.Path(s.ref.ref), tagOrDigest)
headers := make(map[string][]string)
headers["Accept"] = manifest.DefaultRequestedManifestMIMETypes
- res, err := s.c.makeRequest(ctx, "GET", path, headers, nil)
+ res, err := s.c.makeRequest(ctx, "GET", path, headers, nil, v2Auth)
if err != nil {
return nil, "", err
}
@@ -137,7 +137,7 @@ func (s *dockerImageSource) getExternalBlob(ctx context.Context, urls []string)
err error
)
for _, url := range urls {
- resp, err = s.c.makeRequestToResolvedURL(ctx, "GET", url, nil, nil, -1, false)
+ resp, err = s.c.makeRequestToResolvedURL(ctx, "GET", url, nil, nil, -1, noAuth)
if err == nil {
if resp.StatusCode != http.StatusOK {
err = errors.Errorf("error fetching external blob from %q: %d", url, resp.StatusCode)
@@ -169,7 +169,7 @@ func (s *dockerImageSource) GetBlob(ctx context.Context, info types.BlobInfo) (i
path := fmt.Sprintf(blobsPath, reference.Path(s.ref.ref), info.Digest.String())
logrus.Debugf("Downloading %s", path)
- res, err := s.c.makeRequest(ctx, "GET", path, nil, nil)
+ res, err := s.c.makeRequest(ctx, "GET", path, nil, nil, v2Auth)
if err != nil {
return nil, 0, err
}
@@ -332,7 +332,7 @@ func deleteImage(ctx context.Context, sys *types.SystemContext, ref dockerRefere
return err
}
getPath := fmt.Sprintf(manifestPath, reference.Path(ref.ref), refTail)
- get, err := c.makeRequest(ctx, "GET", getPath, headers, nil)
+ get, err := c.makeRequest(ctx, "GET", getPath, headers, nil, v2Auth)
if err != nil {
return err
}
@@ -354,7 +354,7 @@ func deleteImage(ctx context.Context, sys *types.SystemContext, ref dockerRefere
// When retrieving the digest from a registry >= 2.3 use the following header:
// "Accept": "application/vnd.docker.distribution.manifest.v2+json"
- delete, err := c.makeRequest(ctx, "DELETE", deletePath, headers, nil)
+ delete, err := c.makeRequest(ctx, "DELETE", deletePath, headers, nil, v2Auth)
if err != nil {
return err
}
diff --git a/vendor/github.com/containers/image/ostree/ostree_dest.go b/vendor/github.com/containers/image/ostree/ostree_dest.go
index 0ae30f1f4..afff7dc1b 100644
--- a/vendor/github.com/containers/image/ostree/ostree_dest.go
+++ b/vendor/github.com/containers/image/ostree/ostree_dest.go
@@ -467,7 +467,9 @@ func (d *ostreeImageDestination) Commit(ctx context.Context) error {
metadata := []string{fmt.Sprintf("docker.manifest=%s", string(d.manifest)),
fmt.Sprintf("signatures=%d", d.signaturesLen),
fmt.Sprintf("docker.digest=%s", string(d.digest))}
- err = d.ostreeCommit(repo, fmt.Sprintf("ociimage/%s", d.ref.branchName), manifestPath, metadata)
+ if err := d.ostreeCommit(repo, fmt.Sprintf("ociimage/%s", d.ref.branchName), manifestPath, metadata); err != nil {
+ return err
+ }
_, err = repo.CommitTransaction()
return err
diff --git a/version/version.go b/version/version.go
index d7c3b683e..7943adee4 100644
--- a/version/version.go
+++ b/version/version.go
@@ -1,4 +1,7 @@
package version
// Version is the version of the build.
+// NOTE: remember to bump the version at the top
+// of the top-level README.md file when this is
+// bumped.
const Version = "0.9.2-dev"