summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/cirrus/lib.sh62
-rwxr-xr-xcontrib/cirrus/logcollector.sh4
-rwxr-xr-xcontrib/cirrus/runner.sh2
-rwxr-xr-xcontrib/cirrus/setup_environment.sh60
-rw-r--r--libpod/define/errors.go3
-rw-r--r--libpod/image/utils.go3
-rw-r--r--pkg/api/handlers/libpod/images.go7
-rw-r--r--pkg/bindings/test/images_test.go2
-rw-r--r--pkg/domain/infra/abi/images.go10
-rw-r--r--pkg/domain/infra/abi/system.go2
-rw-r--r--pkg/terminal/util.go6
-rw-r--r--test/apiv2/10-images.at2
-rw-r--r--test/apiv2/12-imagesMore.at4
-rw-r--r--test/apiv2/20-containers.at2
-rw-r--r--test/e2e/build_test.go2
-rw-r--r--test/e2e/config.go20
-rw-r--r--test/e2e/config_amd64.go2
-rw-r--r--test/e2e/create_test.go4
-rw-r--r--test/e2e/exists_test.go1
-rw-r--r--test/e2e/healthcheck_run_test.go2
-rw-r--r--test/e2e/images_test.go51
-rw-r--r--test/e2e/inspect_test.go2
-rw-r--r--test/e2e/load_test.go2
-rw-r--r--test/e2e/manifest_test.go2
-rw-r--r--test/e2e/play_kube_test.go4
-rw-r--r--test/e2e/pod_create_test.go4
-rw-r--r--test/e2e/ps_test.go11
-rw-r--r--test/e2e/pull_test.go12
-rw-r--r--test/e2e/rmi_test.go6
-rw-r--r--test/e2e/run_entrypoint_test.go14
-rw-r--r--test/e2e/save_test.go2
-rw-r--r--test/e2e/systemd_test.go2
-rw-r--r--test/e2e/tag_test.go6
-rw-r--r--test/e2e/tree_test.go6
-rw-r--r--test/registries.conf21
-rw-r--r--test/utils/utils.go19
-rw-r--r--vendor/golang.org/x/crypto/ssh/knownhosts/knownhosts.go540
-rw-r--r--vendor/modules.txt1
38 files changed, 742 insertions, 163 deletions
diff --git a/contrib/cirrus/lib.sh b/contrib/cirrus/lib.sh
index e5124d8e4..050fb16f3 100644
--- a/contrib/cirrus/lib.sh
+++ b/contrib/cirrus/lib.sh
@@ -6,25 +6,23 @@
# BEGIN Global export of all variables
set -a
-if [[ "$CI" == "true" ]]; then
- # Due to differences across platforms and runtime execution environments,
- # handling of the (otherwise) default shell setup is non-uniform. Rather
- # than attempt to workaround differences, simply force-load/set required
- # items every time this library is utilized.
- source /etc/profile
- source /etc/environment
- USER="$(whoami)"
- HOME="$(getent passwd $USER | cut -d : -f 6)"
- # Some platforms set and make this read-only
- [[ -n "$UID" ]] || \
- UID=$(getent passwd $USER | cut -d : -f 3)
- GID=$(getent passwd $USER | cut -d : -f 4)
-fi
+# Due to differences across platforms and runtime execution environments,
+# handling of the (otherwise) default shell setup is non-uniform. Rather
+# than attempt to workaround differences, simply force-load/set required
+# items every time this library is utilized.
+source /etc/profile
+source /etc/environment
+if [[ -r "/etc/ci_environment" ]]; then source /etc/ci_environment; fi
+USER="$(whoami)"
+HOME="$(getent passwd $USER | cut -d : -f 6)"
+# Some platforms set and make this read-only
+[[ -n "$UID" ]] || \
+ UID=$(getent passwd $USER | cut -d : -f 3)
# During VM Image build, the 'containers/automation' installation
-# was performed. The final step of that installation sets the
-# installation location in $AUTOMATION_LIB_PATH in /etc/environment
-# or in the default shell profile.
+# was performed. The final step of installation sets the library
+# location $AUTOMATION_LIB_PATH in /etc/environment or in the
+# default shell profile depending on distribution.
# shellcheck disable=SC2154
if [[ -n "$AUTOMATION_LIB_PATH" ]]; then
for libname in defaults anchors console_output utils; do
@@ -88,8 +86,10 @@ CIRRUS_BUILD_ID=${CIRRUS_BUILD_ID:-$RANDOM$(date +%s)} # must be short and uniq
# The starting place for linting and code validation
EPOCH_TEST_COMMIT="$CIRRUS_BASE_SHA"
-# Regex of env. vars. to explicitly pass when executing tests
-# inside a container or as a rootless user
+# Regex defining all CI-releated env. vars. necessary for all possible
+# testing operations on all platforms and versions. This is necessary
+# to avoid needlessly passing through global/system values across
+# contexts, such as host->container or root->rootless user
PASSTHROUGH_ENV_RE='(^CI.*)|(^CIRRUS)|(^DISTRO_NV)|(^GOPATH)|(^GOCACHE)|(^GOSRC)|(^SCRIPT_BASE)|(CGROUP_MANAGER)|(OCI_RUNTIME)|(^TEST.*)|(^PODBIN_NAME)|(^PRIV_NAME)|(^ALT_NAME)|(^ROOTLESS_USER)|(SKIP_USERNS)|(.*_NAME)|(.*_FQIN)'
# Unsafe env. vars for display
SECRET_ENV_RE='(ACCOUNT)|(GC[EP]..+)|(SSH)|(PASSWORD)|(TOKEN)'
@@ -107,10 +107,8 @@ lilto() { err_retry 8 1000 "" "$@"; } # just over 4 minutes max
bigto() { err_retry 7 5670 "" "$@"; } # 12 minutes max
# Print shell-escaped variable=value pairs, one per line, based on
-# variable name matching a regex. This is intended to support
-# passthrough of CI variables from host -> container or from root -> user.
-# For all other vars. we rely on tooling to load this library from inside
-# the container or as rootless user to pickup the remainder.
+# variable name matching a regex. This is intended to catch
+# variables being passed down from higher layers, like Cirrus-CI.
passthrough_envars(){
local xchars
local envname
@@ -176,22 +174,7 @@ setup_rootless() {
echo "${ROOTLESS_USER}:$[rootless_uid * 100]:65536" | \
tee -a /etc/subuid >> /etc/subgid
- # Env. vars set by Cirrus and setup_environment.sh must be explicitly
- # transferred to the test-user.
- msg "Configuring rootless user's environment variables:"
-
- (
- echo "# Added by ${BASH_SOURCE[0]} ${FUNCNAME[0]}()"
- echo "export SETUP_ENVIRONMENT=1"
- ) >> "/home/$ROOTLESS_USER/.bashrc"
-
- while read -r env_var_val; do
- echo "export $env_var_val" >> "/home/$ROOTLESS_USER/.bashrc"
- done <<<"$(passthrough_envars)"
- chown $ROOTLESS_USER:$ROOTLESS_USER "/home/$ROOTLESS_USER/.bashrc"
- cat "/home/$ROOTLESS_USER/.bashrc" | indent 2
-
- msg "Ensure the systems ssh process is up and running within 5 minutes"
+ msg "Ensure the ssh daemon is up and running within 5 minutes"
systemctl start sshd
lilto ssh $ROOTLESS_USER@localhost \
-o UserKnownHostsFile=/dev/null \
@@ -208,6 +191,7 @@ install_test_configs() {
# as the default). This config prevents allocation of network address space used
# by default in google cloud. https://cloud.google.com/vpc/docs/vpc#ip-ranges
install -v -D -m 644 $SCRIPT_BASE/99-do-not-use-google-subnets.conflist /etc/cni/net.d/
+
install -v -D -m 644 ./test/registries.conf /etc/containers/
}
diff --git a/contrib/cirrus/logcollector.sh b/contrib/cirrus/logcollector.sh
index 9dcc252c0..746bccec9 100755
--- a/contrib/cirrus/logcollector.sh
+++ b/contrib/cirrus/logcollector.sh
@@ -45,8 +45,10 @@ case $1 in
containernetworking-plugins \
containers-common \
criu \
+ crun \
golang \
podman \
+ runc \
skopeo \
slirp4netns \
)
@@ -56,9 +58,7 @@ case $1 in
PKG_LST_CMD='rpm -q --qf=%{N}-%{V}-%{R}-%{ARCH}\n'
PKG_NAMES+=(\
container-selinux \
- crun \
libseccomp \
- runc \
)
;;
ubuntu*)
diff --git a/contrib/cirrus/runner.sh b/contrib/cirrus/runner.sh
index b97a696d9..084b196a9 100755
--- a/contrib/cirrus/runner.sh
+++ b/contrib/cirrus/runner.sh
@@ -40,7 +40,7 @@ function _run_automation() {
req_env_vars CI DEST_BRANCH IMAGE_SUFFIX TEST_FLAVOR TEST_ENVIRON \
PODBIN_NAME PRIV_NAME DISTRO_NV CONTAINER USER HOME \
- UID GID AUTOMATION_LIB_PATH SCRIPT_BASE OS_RELEASE_ID \
+ UID AUTOMATION_LIB_PATH SCRIPT_BASE OS_RELEASE_ID \
OS_RELEASE_VER CG_FS_TYPE
bigto ooe.sh dnf install -y ShellCheck # small/quick addition
$SCRIPT_BASE/shellcheck.sh
diff --git a/contrib/cirrus/setup_environment.sh b/contrib/cirrus/setup_environment.sh
index 3135a5e65..a3840d7e6 100755
--- a/contrib/cirrus/setup_environment.sh
+++ b/contrib/cirrus/setup_environment.sh
@@ -1,5 +1,12 @@
#!/usr/bin/env bash
+# This script is intended to be executed early by automation before
+# performing other substantial operations. It relies heavily on
+# desired setup information being passed in environment variables
+# from Cirrus-CI and/or other orchestration tooling. To that end,
+# VM's must always be considered single-purpose, single-use,
+# disposable entities. i.e. One setup, one test, then always discarded.
+
set -e
# shellcheck source=./contrib/cirrus/lib.sh
@@ -29,6 +36,17 @@ do
fi
done
+# Ensure that all lower-level contexts and child-processes have
+# ready access to higher level orchestration (e.g Cirrus-CI)
+# variables.
+echo -e "\n# Begin single-use VM global variables (${BASH_SOURCE[0]})" \
+ > "/etc/ci_environment"
+(
+ while read -r env_var_val; do
+ echo "$env_var_val"
+ done <<<"$(passthrough_envars)"
+) >> "/etc/ci_environment"
+
# This is a possible manual maintenance gaff, check to be sure everything matches.
# shellcheck disable=SC2154
[[ "$DISTRO_NV" == "$OS_REL_VER" ]] || \
@@ -50,9 +68,9 @@ case "$CG_FS_TYPE" in
if ((CONTAINER==0)); then
warn "Forcing testing with runc instead of crun"
if [[ "$OS_RELEASE_ID" == "ubuntu" ]]; then
- echo "export OCI_RUNTIME=/usr/lib/cri-o-runc/sbin/runc" >> /etc/environment
+ echo "OCI_RUNTIME=/usr/lib/cri-o-runc/sbin/runc" >> /etc/ci_environment
else
- echo "export OCI_RUNTIME=runc" >> /etc/environment
+ echo "OCI_RUNTIME=runc" >> /etc/ci_environment
fi
fi
;;
@@ -61,7 +79,7 @@ case "$CG_FS_TYPE" in
# This is necessary since we've built/installed from source,
# which uses runc as the default.
warn "Forcing testing with crun instead of runc"
- echo "export OCI_RUNTIME=crun" >> /etc/environment
+ echo "OCI_RUNTIME=crun" >> /etc/ci_environment
fi
;;
*) die_unknown CG_FS_TYPE
@@ -91,15 +109,13 @@ case "$TEST_ENVIRON" in
host)
if [[ "$OS_RELEASE_ID" == "fedora" ]]; then
# The e2e tests wrongly guess `--cgroup-manager cgroupfs`
- msg "Forcing CGROUP_MANAGER=systemd"
- _cgm="export CGROUP_MANAGER=systemd"
- echo "$_cgm" >> /etc/environment
- source /etc/environment
+ warn "Forcing CGROUP_MANAGER=systemd"
+ echo "CGROUP_MANAGER=systemd" >> /etc/ci_environment
fi
;;
container)
if ((CONTAINER==0)); then # not yet inside a container
- msg "Force loading iptables modules"
+ warn "Force loading iptables modules"
# Since CRIU 3.11, uses iptables to lock and unlock
# the network during checkpoint and restore. Needs
# the following two modules loaded on the host.
@@ -107,10 +123,8 @@ case "$TEST_ENVIRON" in
modprobe iptable_nat || :
else
# The e2e tests wrongly guess `--cgroup-manager systemd`
- msg "Forcing CGROUP_MANAGER=cgroupfs"
- _cgm="export CGROUP_MANAGER=cgroupfs"
- echo "$_cgm" >> /etc/environment
- source /etc/environment
+ warn "Forcing CGROUP_MANAGER=cgroupfs"
+ echo "CGROUP_MANAGER=cgroupfs" >> /etc/ci_environment
fi
;;
*) die_unknown TEST_ENVIRON
@@ -123,15 +137,14 @@ case "$PRIV_NAME" in
if [[ "$TEST_ENVIRON" == "container" ]] && ((container)); then
# There's no practical way to detect userns w/in a container
# affected/related tests are sensitive to this variable.
- _suns='export SKIP_USERNS=1'
- echo "$_suns" >> /etc/environment
- source /etc/environment
+ warn "Disabling usernamespace integration testing"
+ echo "SKIP_USERNS=1" >> /etc/ci_environment
fi
;;
rootless)
- _ru="export ROOTLESS_USER='${ROOTLESS_USER:-some${RANDOM}dude}'"
- echo "$_ru" >> /etc/environment
- source /etc/environment
+ # Needs to exist for setup_rootless()
+ ROOTLESS_USER="${ROOTLESS_USER:-some${RANDOM}dude}"
+ echo "ROOTLESS_USER=$ROOTLESS_USER" >> /etc/ci_environment
setup_rootless
;;
*) die_unknown PRIV_NAME
@@ -178,11 +191,18 @@ case "$TEST_FLAVOR" in
remove_packaged_podman_files
make install PREFIX=/usr ETCDIR=/etc
fi
+
+ install_test_configs
;;
vendor) make clean ;;
release) ;;
*) die_unknown TEST_FLAVOR
esac
-# Must be the very last command. Establishes successful setup.
-echo 'export SETUP_ENVIRONMENT=1' >> /etc/environment
+# Must be the very last command. Prevents setup from running twice.
+echo 'SETUP_ENVIRONMENT=1' >> /etc/ci_environment
+echo -e "\n# End of global variable definitions" \
+ >> /etc/ci_environment
+
+msg "Global CI Environment vars.:"
+cat /etc/ci_environment | sort | indent
diff --git a/libpod/define/errors.go b/libpod/define/errors.go
index 627928ef7..300e0d7ca 100644
--- a/libpod/define/errors.go
+++ b/libpod/define/errors.go
@@ -14,6 +14,9 @@ var (
// ErrNoSuchImage indicates the requested image does not exist
ErrNoSuchImage = errors.New("no such image")
+ // ErrMultipleImages found multiple name and tag matches
+ ErrMultipleImages = errors.New("found multiple name and tag matches")
+
// ErrNoSuchTag indicates the requested image tag does not exist
ErrNoSuchTag = errors.New("no such tag")
diff --git a/libpod/image/utils.go b/libpod/image/utils.go
index 2538f429b..7429a7f10 100644
--- a/libpod/image/utils.go
+++ b/libpod/image/utils.go
@@ -11,6 +11,7 @@ import (
"github.com/containers/image/v5/docker/reference"
"github.com/containers/image/v5/signature"
"github.com/containers/image/v5/types"
+ "github.com/containers/podman/v2/libpod/define"
"github.com/containers/storage"
"github.com/pkg/errors"
)
@@ -42,7 +43,7 @@ func findImageInRepotags(search imageParts, images []*Image) (*storage.Image, er
if len(results) == 0 {
return &storage.Image{}, errors.Errorf("unable to find a name and tag match for %s in repotags", searchName)
} else if len(results) > 1 {
- return &storage.Image{}, errors.Errorf("found multiple name and tag matches for %s in repotags", searchName)
+ return &storage.Image{}, errors.Wrapf(define.ErrMultipleImages, searchName)
}
return results[0], nil
}
diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go
index 598a46abe..55264b3b6 100644
--- a/pkg/api/handlers/libpod/images.go
+++ b/pkg/api/handlers/libpod/images.go
@@ -44,11 +44,16 @@ func ImageExists(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
name := utils.GetName(r)
- _, err := runtime.ImageRuntime().NewFromLocal(name)
+ ir := abi.ImageEngine{Libpod: runtime}
+ report, err := ir.Exists(r.Context(), name)
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusNotFound, errors.Wrapf(err, "failed to find image %s", name))
return
}
+ if !report.Value {
+ utils.Error(w, "Something went wrong.", http.StatusNotFound, errors.Wrapf(nil, "failed to find image %s", name))
+ return
+ }
utils.WriteResponse(w, http.StatusNoContent, "")
}
diff --git a/pkg/bindings/test/images_test.go b/pkg/bindings/test/images_test.go
index 681855293..7d9415f91 100644
--- a/pkg/bindings/test/images_test.go
+++ b/pkg/bindings/test/images_test.go
@@ -166,7 +166,7 @@ var _ = Describe("Podman images", func() {
// Adding one more image. There Should be no errors in the response.
// And the count should be three now.
- bt.Pull("busybox:glibc")
+ bt.Pull("testimage:20200929")
imageSummary, err = images.List(bt.conn, nil, nil)
Expect(err).To(BeNil())
Expect(len(imageSummary)).To(Equal(3))
diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go
index 25335cf11..ef0e15264 100644
--- a/pkg/domain/infra/abi/images.go
+++ b/pkg/domain/infra/abi/images.go
@@ -39,8 +39,14 @@ const SignatureStoreDir = "/var/lib/containers/sigstore"
func (ir *ImageEngine) Exists(_ context.Context, nameOrID string) (*entities.BoolReport, error) {
_, err := ir.Libpod.ImageRuntime().NewFromLocal(nameOrID)
- if err != nil && errors.Cause(err) != define.ErrNoSuchImage {
- return nil, err
+ if err != nil {
+ if errors.Cause(err) == define.ErrMultipleImages {
+ return &entities.BoolReport{Value: true}, nil
+ } else {
+ if errors.Cause(err) != define.ErrNoSuchImage {
+ return nil, err
+ }
+ }
}
return &entities.BoolReport{Value: err == nil}, nil
}
diff --git a/pkg/domain/infra/abi/system.go b/pkg/domain/infra/abi/system.go
index 57c098166..613c4a6d8 100644
--- a/pkg/domain/infra/abi/system.go
+++ b/pkg/domain/infra/abi/system.go
@@ -123,7 +123,7 @@ func (ic *ContainerEngine) SetupRootless(_ context.Context, cmd *cobra.Command)
}
}
if err != nil {
- logrus.Error(err)
+ logrus.Error(errors.Wrapf(err, "invalid internal status, try resetting the pause process with %q", os.Args[0]+" system migrate"))
os.Exit(1)
}
if became {
diff --git a/pkg/terminal/util.go b/pkg/terminal/util.go
index ab3dc54e4..169bec2af 100644
--- a/pkg/terminal/util.go
+++ b/pkg/terminal/util.go
@@ -12,6 +12,7 @@ import (
"github.com/sirupsen/logrus"
"golang.org/x/crypto/ssh"
+ "golang.org/x/crypto/ssh/knownhosts"
"golang.org/x/crypto/ssh/terminal"
"k8s.io/client-go/util/homedir"
)
@@ -114,6 +115,9 @@ func HostKey(host string) ssh.PublicKey {
return nil
}
+ // support -H parameter for ssh-keyscan
+ hashhost := knownhosts.HashHostname(host)
+
scanner := bufio.NewScanner(fd)
for scanner.Scan() {
_, hosts, key, _, _, err := ssh.ParseKnownHosts(scanner.Bytes())
@@ -123,7 +127,7 @@ func HostKey(host string) ssh.PublicKey {
}
for _, h := range hosts {
- if h == host {
+ if h == host || h == hashhost {
return key
}
}
diff --git a/test/apiv2/10-images.at b/test/apiv2/10-images.at
index 1f5722a0c..c105a9278 100644
--- a/test/apiv2/10-images.at
+++ b/test/apiv2/10-images.at
@@ -43,7 +43,7 @@ t POST "images/create?fromImage=alpine" '' 200
t POST "images/create?fromImage=alpine&tag=latest" '' 200
-t POST "images/create?fromImage=docker.io/library/alpine&tag=sha256:acd3ca9941a85e8ed16515bfc5328e4e2f8c128caa72959a58a127b7801ee01f" '' 200
+t POST "images/create?fromImage=quay.io/libpod/alpine&tag=sha256:fa93b01658e3a5a1686dc3ae55f170d8de487006fb53a28efcd12ab0710a2e5f" '' 200
# Display the image history
t GET libpod/images/nonesuch/history 404
diff --git a/test/apiv2/12-imagesMore.at b/test/apiv2/12-imagesMore.at
index d720ffa65..896e685cd 100644
--- a/test/apiv2/12-imagesMore.at
+++ b/test/apiv2/12-imagesMore.at
@@ -23,7 +23,7 @@ t GET libpod/images/$IMAGE/json 200 \
.RepoTags[1]=localhost:5000/myrepo:mytag
# Run registry container
-podman run -d --name registry -p 5000:5000 docker.io/library/registry:2.6 /entrypoint.sh /etc/docker/registry/config.yml
+podman run -d --name registry -p 5000:5000 quay.io/libpod/registry:2.6 /entrypoint.sh /etc/docker/registry/config.yml
# Push to local registry
# FIXME: this is failing:
@@ -44,5 +44,5 @@ t DELETE libpod/containers/registry?force=true 204
# Remove images
t DELETE libpod/images/$IMAGE 200 \
.ExitCode=0
-t DELETE libpod/images/docker.io/library/registry:2.6 200 \
+t DELETE libpod/images/quay.io/libpod/registry:2.6 200 \
.ExitCode=0
diff --git a/test/apiv2/20-containers.at b/test/apiv2/20-containers.at
index c7055dfc4..b35c27215 100644
--- a/test/apiv2/20-containers.at
+++ b/test/apiv2/20-containers.at
@@ -4,7 +4,7 @@
#
# WORKDIR=/data
-ENV_WORKDIR_IMG=docker.io/library/redis:alpine
+ENV_WORKDIR_IMG=quay.io/libpod/testimage:20200929
podman pull $IMAGE &>/dev/null
podman pull $ENV_WORKDIR_IMG &>/dev/null
diff --git a/test/e2e/build_test.go b/test/e2e/build_test.go
index 572e55fe5..ea15e2b8d 100644
--- a/test/e2e/build_test.go
+++ b/test/e2e/build_test.go
@@ -226,7 +226,7 @@ var _ = Describe("Podman build", func() {
podmanTest.StartRemoteService()
}
podmanTest.RestoreAllArtifacts()
- dockerfile := `FROM docker.io/library/alpine:latest
+ dockerfile := `FROM quay.io/libpod/alpine:latest
RUN printenv http_proxy`
dockerfilePath := filepath.Join(podmanTest.TempDir, "Dockerfile")
diff --git a/test/e2e/config.go b/test/e2e/config.go
index 54e39f9d2..e66cd6846 100644
--- a/test/e2e/config.go
+++ b/test/e2e/config.go
@@ -1,18 +1,18 @@
package integration
var (
- redis = "docker.io/library/redis:alpine"
+ redis = "quay.io/libpod/redis:alpine"
fedoraMinimal = "quay.io/libpod/fedora-minimal:latest"
- ALPINE = "docker.io/library/alpine:latest"
- ALPINELISTTAG = "docker.io/library/alpine:3.10.2"
- ALPINELISTDIGEST = "docker.io/library/alpine@sha256:72c42ed48c3a2db31b7dafe17d275b634664a708d901ec9fd57b1529280f01fb"
- ALPINEAMD64DIGEST = "docker.io/library/alpine@sha256:acd3ca9941a85e8ed16515bfc5328e4e2f8c128caa72959a58a127b7801ee01f"
+ ALPINE = "quay.io/libpod/alpine:latest"
+ ALPINELISTTAG = "quay.io/libpod/alpine:3.10.2"
+ ALPINELISTDIGEST = "quay.io/libpod/alpine@sha256:fa93b01658e3a5a1686dc3ae55f170d8de487006fb53a28efcd12ab0710a2e5f"
+ ALPINEAMD64DIGEST = "quay.io/libpod/alpine@sha256:634a8f35b5f16dcf4aaa0822adc0b1964bb786fca12f6831de8ddc45e5986a00"
ALPINEAMD64ID = "961769676411f082461f9ef46626dd7a2d1e2b2a38e6a44364bcbecf51e66dd4"
- ALPINEARM64DIGEST = "docker.io/library/alpine@sha256:db7f3dcef3d586f7dd123f107c93d7911515a5991c4b9e51fa2a43e46335a43e"
+ ALPINEARM64DIGEST = "quay.io/libpod/alpine@sha256:f270dcd11e64b85919c3bab66886e59d677cf657528ac0e4805d3c71e458e525"
ALPINEARM64ID = "915beeae46751fc564998c79e73a1026542e945ca4f73dc841d09ccc6c2c0672"
infra = "k8s.gcr.io/pause:3.2"
- BB = "docker.io/library/busybox:latest"
- healthcheck = "docker.io/libpod/alpine_healthcheck:latest"
+ BB = "quay.io/libpod/busybox:latest"
+ healthcheck = "quay.io/libpod/alpine_healthcheck:latest"
ImageCacheDir = "/tmp/podman/imagecachedir"
fedoraToolbox = "registry.fedoraproject.org/f32/fedora-toolbox:latest"
@@ -20,8 +20,8 @@ var (
// The intention behind blocking all syscalls is to prevent
// regressions in the future. The required syscalls can vary
// depending on which runtime we're using.
- alpineSeccomp = "docker.io/libpod/alpine-with-seccomp:label"
+ alpineSeccomp = "quay.io/libpod/alpine-with-seccomp:label"
// This image has a bogus/invalid seccomp profile which should
// yield a json error when being read.
- alpineBogusSeccomp = "docker.io/libpod/alpine-with-bogus-seccomp:label"
+ alpineBogusSeccomp = "quay.io/libpod/alpine-with-bogus-seccomp:label"
)
diff --git a/test/e2e/config_amd64.go b/test/e2e/config_amd64.go
index 151120058..2323c7e6b 100644
--- a/test/e2e/config_amd64.go
+++ b/test/e2e/config_amd64.go
@@ -8,7 +8,7 @@ var (
CACHE_IMAGES = []string{ALPINE, BB, fedoraMinimal, nginx, redis, registry, infra, labels, healthcheck, ubi_init, ubi_minimal}
nginx = "quay.io/libpod/alpine_nginx:latest"
BB_GLIBC = "docker.io/library/busybox:glibc"
- registry = "docker.io/library/registry:2.6"
+ registry = "quay.io/libpod/registry:2.6"
labels = "quay.io/libpod/alpine_labels:latest"
ubi_minimal = "registry.access.redhat.com/ubi8-minimal"
ubi_init = "registry.access.redhat.com/ubi8-init"
diff --git a/test/e2e/create_test.go b/test/e2e/create_test.go
index 6b0f7a7af..d9378abca 100644
--- a/test/e2e/create_test.go
+++ b/test/e2e/create_test.go
@@ -271,11 +271,11 @@ var _ = Describe("Podman create", func() {
})
It("podman create --pull", func() {
- session := podmanTest.PodmanNoCache([]string{"create", "--pull", "never", "--name=foo", "debian"})
+ session := podmanTest.PodmanNoCache([]string{"create", "--pull", "never", "--name=foo", "testimage:00000000"})
session.WaitWithDefaultTimeout()
Expect(session).To(ExitWithError())
- session = podmanTest.PodmanNoCache([]string{"create", "--pull", "always", "--name=foo", "debian"})
+ session = podmanTest.PodmanNoCache([]string{"create", "--pull", "always", "--name=foo", "testimage:00000000"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})
diff --git a/test/e2e/exists_test.go b/test/e2e/exists_test.go
index 1076dfc61..1408e59bb 100644
--- a/test/e2e/exists_test.go
+++ b/test/e2e/exists_test.go
@@ -39,6 +39,7 @@ var _ = Describe("Podman image|container exists", func() {
Expect(session).Should(Exit(0))
})
It("podman image exists in local storage by short name", func() {
+ Skip("FIXME-8165: shortnames don't seem to work with quay (#8176)")
session := podmanTest.Podman([]string{"image", "exists", "alpine"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
diff --git a/test/e2e/healthcheck_run_test.go b/test/e2e/healthcheck_run_test.go
index 71e73af9c..403f15fa7 100644
--- a/test/e2e/healthcheck_run_test.go
+++ b/test/e2e/healthcheck_run_test.go
@@ -81,7 +81,7 @@ var _ = Describe("Podman healthcheck run", func() {
})
It("podman healthcheck that should fail", func() {
- session := podmanTest.Podman([]string{"run", "-dt", "--name", "hc", "docker.io/libpod/badhealthcheck:latest"})
+ session := podmanTest.Podman([]string{"run", "-dt", "--name", "hc", "quay.io/libpod/badhealthcheck:latest"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
diff --git a/test/e2e/images_test.go b/test/e2e/images_test.go
index 9344132d9..b42061c20 100644
--- a/test/e2e/images_test.go
+++ b/test/e2e/images_test.go
@@ -41,8 +41,8 @@ var _ = Describe("Podman images", func() {
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
Expect(len(session.OutputToStringArray())).To(BeNumerically(">", 2))
- Expect(session.LineInOuputStartsWith("docker.io/library/alpine")).To(BeTrue())
- Expect(session.LineInOuputStartsWith("docker.io/library/busybox")).To(BeTrue())
+ Expect(session.LineInOuputStartsWith("quay.io/libpod/alpine")).To(BeTrue())
+ Expect(session.LineInOuputStartsWith("quay.io/libpod/busybox")).To(BeTrue())
})
It("podman images with no images prints header", func() {
@@ -62,8 +62,8 @@ var _ = Describe("Podman images", func() {
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
Expect(len(session.OutputToStringArray())).To(BeNumerically(">", 2))
- Expect(session.LineInOuputStartsWith("docker.io/library/alpine")).To(BeTrue())
- Expect(session.LineInOuputStartsWith("docker.io/library/busybox")).To(BeTrue())
+ Expect(session.LineInOuputStartsWith("quay.io/libpod/alpine")).To(BeTrue())
+ Expect(session.LineInOuputStartsWith("quay.io/libpod/busybox")).To(BeTrue())
})
It("podman images with multiple tags", func() {
@@ -80,13 +80,13 @@ var _ = Describe("Podman images", func() {
session = podmanTest.PodmanNoCache([]string{"images"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
- session.LineInOutputContainsTag("docker.io/library/alpine", "latest")
- session.LineInOutputContainsTag("docker.io/library/busybox", "glibc")
- session.LineInOutputContainsTag("foo", "a")
- session.LineInOutputContainsTag("foo", "b")
- session.LineInOutputContainsTag("foo", "c")
- session.LineInOutputContainsTag("bar", "a")
- session.LineInOutputContainsTag("bar", "b")
+ Expect(session.LineInOutputContainsTag("quay.io/libpod/alpine", "latest")).To(BeTrue())
+ Expect(session.LineInOutputContainsTag("quay.io/libpod/busybox", "latest")).To(BeTrue())
+ Expect(session.LineInOutputContainsTag("localhost/foo", "a")).To(BeTrue())
+ Expect(session.LineInOutputContainsTag("localhost/foo", "b")).To(BeTrue())
+ Expect(session.LineInOutputContainsTag("localhost/foo", "c")).To(BeTrue())
+ Expect(session.LineInOutputContainsTag("localhost/bar", "a")).To(BeTrue())
+ Expect(session.LineInOutputContainsTag("localhost/bar", "b")).To(BeTrue())
session = podmanTest.PodmanNoCache([]string{"images", "-qn"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
@@ -98,8 +98,8 @@ var _ = Describe("Podman images", func() {
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
Expect(len(session.OutputToStringArray())).To(BeNumerically(">", 2))
- Expect(session.LineInOuputStartsWith("docker.io/library/alpine")).To(BeTrue())
- Expect(session.LineInOuputStartsWith("docker.io/library/busybox")).To(BeTrue())
+ Expect(session.LineInOuputStartsWith("quay.io/libpod/alpine")).To(BeTrue())
+ Expect(session.LineInOuputStartsWith("quay.io/libpod/busybox")).To(BeTrue())
})
It("podman empty images list in JSON format", func() {
@@ -152,10 +152,10 @@ var _ = Describe("Podman images", func() {
It("podman images filter reference", func() {
podmanTest.RestoreAllArtifacts()
- result := podmanTest.PodmanNoCache([]string{"images", "-q", "-f", "reference=docker.io*"})
+ result := podmanTest.PodmanNoCache([]string{"images", "-q", "-f", "reference=quay.io*"})
result.WaitWithDefaultTimeout()
Expect(result).Should(Exit(0))
- Expect(len(result.OutputToStringArray())).To(Equal(2))
+ Expect(len(result.OutputToStringArray())).To(Equal(3))
retapline := podmanTest.PodmanNoCache([]string{"images", "-f", "reference=a*pine"})
retapline.WaitWithDefaultTimeout()
@@ -176,7 +176,7 @@ var _ = Describe("Podman images", func() {
})
It("podman images filter before image", func() {
- dockerfile := `FROM docker.io/library/alpine:latest
+ dockerfile := `FROM quay.io/libpod/alpine:latest
RUN apk update && apk add strace
`
podmanTest.BuildImage(dockerfile, "foobar.com/before:latest", "false")
@@ -188,7 +188,7 @@ RUN apk update && apk add strace
})
It("podman images workingdir from image", func() {
- dockerfile := `FROM docker.io/library/alpine:latest
+ dockerfile := `FROM quay.io/libpod/alpine:latest
WORKDIR /test
`
podmanTest.BuildImage(dockerfile, "foobar.com/workdir:latest", "false")
@@ -204,10 +204,10 @@ WORKDIR /test
rmi.WaitWithDefaultTimeout()
Expect(rmi).Should(Exit(0))
- dockerfile := `FROM docker.io/library/alpine:latest
+ dockerfile := `FROM quay.io/libpod/alpine:latest
`
podmanTest.BuildImage(dockerfile, "foobar.com/before:latest", "false")
- result := podmanTest.PodmanNoCache([]string{"images", "-q", "-f", "after=docker.io/library/alpine:latest"})
+ result := podmanTest.PodmanNoCache([]string{"images", "-q", "-f", "after=quay.io/libpod/alpine:latest"})
result.WaitWithDefaultTimeout()
Expect(result).Should(Exit(0))
Expect(len(result.OutputToStringArray())).To(Equal(0))
@@ -219,17 +219,17 @@ WORKDIR /test
rmi.WaitWithDefaultTimeout()
Expect(rmi).Should(Exit(0))
- dockerfile := `FROM docker.io/library/alpine:latest
+ dockerfile := `FROM quay.io/libpod/alpine:latest
`
podmanTest.BuildImage(dockerfile, "foobar.com/before:latest", "false")
- result := podmanTest.PodmanNoCache([]string{"image", "list", "-q", "-f", "after=docker.io/library/alpine:latest"})
+ result := podmanTest.PodmanNoCache([]string{"image", "list", "-q", "-f", "after=quay.io/libpod/alpine:latest"})
result.WaitWithDefaultTimeout()
Expect(result).Should(Exit(0))
Expect(result.OutputToStringArray()).Should(HaveLen(0), "list filter output: %q", result.OutputToString())
})
It("podman images filter dangling", func() {
- dockerfile := `FROM docker.io/library/alpine:latest
+ dockerfile := `FROM quay.io/libpod/alpine:latest
`
podmanTest.BuildImage(dockerfile, "foobar.com/before:latest", "false")
podmanTest.BuildImage(dockerfile, "foobar.com/before:latest", "false")
@@ -240,6 +240,7 @@ WORKDIR /test
})
It("podman pull by digest and list --all", func() {
+ Skip("FIXME-8165: 'rmi -af' fails with 'layer not known' (#6510)")
// Prevent regressing on issue #7651.
digestPullAndList := func(noneTag bool) {
session := podmanTest.Podman([]string{"pull", ALPINEAMD64DIGEST})
@@ -341,7 +342,7 @@ WORKDIR /test
It("podman images --all flag", func() {
SkipIfRemote("FIXME This should work on podman-remote, problem is with podman-remote build")
podmanTest.RestoreAllArtifacts()
- dockerfile := `FROM docker.io/library/alpine:latest
+ dockerfile := `FROM quay.io/libpod/alpine:latest
RUN mkdir hello
RUN touch test.txt
ENV foo=bar
@@ -359,7 +360,7 @@ ENV foo=bar
})
It("podman images filter by label", func() {
- dockerfile := `FROM docker.io/library/alpine:latest
+ dockerfile := `FROM quay.io/libpod/alpine:latest
LABEL version="1.0"
LABEL "com.example.vendor"="Example Vendor"
`
@@ -436,7 +437,7 @@ LABEL "com.example.vendor"="Example Vendor"
})
It("podman images --filter readonly", func() {
- dockerfile := `FROM docker.io/library/alpine:latest
+ dockerfile := `FROM quay.io/libpod/alpine:latest
`
podmanTest.BuildImage(dockerfile, "foobar.com/before:latest", "false")
result := podmanTest.Podman([]string{"images", "-f", "readonly=true"})
diff --git a/test/e2e/inspect_test.go b/test/e2e/inspect_test.go
index e8a82f9a1..9ede3384f 100644
--- a/test/e2e/inspect_test.go
+++ b/test/e2e/inspect_test.go
@@ -40,7 +40,7 @@ var _ = Describe("Podman inspect", func() {
Expect(session.ExitCode()).To(Equal(0))
Expect(session.IsJSONOutputValid()).To(BeTrue())
imageData := session.InspectImageJSON()
- Expect(imageData[0].RepoTags[0]).To(Equal("docker.io/library/alpine:latest"))
+ Expect(imageData[0].RepoTags[0]).To(Equal("quay.io/libpod/alpine:latest"))
})
It("podman inspect bogus container", func() {
diff --git a/test/e2e/load_test.go b/test/e2e/load_test.go
index dd91381d9..e85a38c66 100644
--- a/test/e2e/load_test.go
+++ b/test/e2e/load_test.go
@@ -166,7 +166,7 @@ var _ = Describe("Podman load", func() {
Skip("skip on ppc64le")
}
outfile := filepath.Join(podmanTest.TempDir, "alpine.tar")
- alpVersion := "docker.io/library/alpine:3.2"
+ alpVersion := "quay.io/libpod/alpine:3.2"
pull := podmanTest.PodmanNoCache([]string{"pull", alpVersion})
pull.WaitWithDefaultTimeout()
diff --git a/test/e2e/manifest_test.go b/test/e2e/manifest_test.go
index b85132814..f984345f4 100644
--- a/test/e2e/manifest_test.go
+++ b/test/e2e/manifest_test.go
@@ -55,7 +55,7 @@ var _ = Describe("Podman manifest", func() {
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.PodmanNoCache([]string{"manifest", "inspect", "docker.io/library/busybox"})
+ session = podmanTest.PodmanNoCache([]string{"manifest", "inspect", "quay.io/libpod/busybox"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
})
diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go
index 7ab8dc6f8..6dcfa9bd8 100644
--- a/test/e2e/play_kube_test.go
+++ b/test/e2e/play_kube_test.go
@@ -1092,7 +1092,7 @@ var _ = Describe("Podman play kube", func() {
})
It("podman play kube with pull always", func() {
- oldBB := "docker.io/library/busybox:1.30.1"
+ oldBB := "quay.io/libpod/busybox:1.30.1"
pull := podmanTest.Podman([]string{"pull", oldBB})
pull.WaitWithDefaultTimeout()
@@ -1123,7 +1123,7 @@ var _ = Describe("Podman play kube", func() {
})
It("podman play kube with latest image should always pull", func() {
- oldBB := "docker.io/library/busybox:1.30.1"
+ oldBB := "quay.io/libpod/busybox:1.30.1"
pull := podmanTest.Podman([]string{"pull", oldBB})
pull.WaitWithDefaultTimeout()
diff --git a/test/e2e/pod_create_test.go b/test/e2e/pod_create_test.go
index 95870788e..be0a2f6f0 100644
--- a/test/e2e/pod_create_test.go
+++ b/test/e2e/pod_create_test.go
@@ -382,7 +382,7 @@ var _ = Describe("Podman pod create", func() {
})
It("podman create pod with --infra-image", func() {
- dockerfile := `FROM docker.io/library/alpine:latest
+ dockerfile := `FROM quay.io/libpod/alpine:latest
entrypoint ["/fromimage"]
`
podmanTest.BuildImage(dockerfile, "localhost/infra", "false")
@@ -409,7 +409,7 @@ entrypoint ["/fromimage"]
})
It("podman create pod with --infra-command --infra-image", func() {
- dockerfile := `FROM docker.io/library/alpine:latest
+ dockerfile := `FROM quay.io/libpod/alpine:latest
entrypoint ["/fromimage"]
`
podmanTest.BuildImage(dockerfile, "localhost/infra", "false")
diff --git a/test/e2e/ps_test.go b/test/e2e/ps_test.go
index 11d0b8c9b..f3a66e58a 100644
--- a/test/e2e/ps_test.go
+++ b/test/e2e/ps_test.go
@@ -232,12 +232,19 @@ var _ = Describe("Podman ps", func() {
})
It("podman ps ancestor filter flag", func() {
- _, ec, _ := podmanTest.RunLsContainer("test1")
+ _, ec, cid := podmanTest.RunLsContainer("test1")
Expect(ec).To(Equal(0))
- result := podmanTest.Podman([]string{"ps", "-a", "--filter", "ancestor=docker.io/library/alpine:latest"})
+ result := podmanTest.Podman([]string{"ps", "-q", "--no-trunc", "-a", "--filter", "ancestor=quay.io/libpod/alpine:latest"})
+ result.WaitWithDefaultTimeout()
+ Expect(result.ExitCode()).To(Equal(0))
+ Expect(result.OutputToString()).To(Equal(cid))
+
+ // Query just by image name, without :latest tag
+ result = podmanTest.Podman([]string{"ps", "-q", "--no-trunc", "-a", "--filter", "ancestor=quay.io/libpod/alpine"})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
+ Expect(result.OutputToString()).To(Equal(cid))
})
It("podman ps id filter flag", func() {
diff --git a/test/e2e/pull_test.go b/test/e2e/pull_test.go
index 08ab50de1..5ccefe285 100644
--- a/test/e2e/pull_test.go
+++ b/test/e2e/pull_test.go
@@ -41,21 +41,21 @@ var _ = Describe("Podman pull", func() {
})
It("podman pull from docker with tag", func() {
- session := podmanTest.PodmanNoCache([]string{"pull", "busybox:glibc"})
+ session := podmanTest.PodmanNoCache([]string{"pull", "quay.io/libpod/testdigest_v2s2:20200210"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.PodmanNoCache([]string{"rmi", "busybox:glibc"})
+ session = podmanTest.PodmanNoCache([]string{"rmi", "testdigest_v2s2:20200210"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})
It("podman pull from docker without tag", func() {
- session := podmanTest.PodmanNoCache([]string{"pull", "busybox"})
+ session := podmanTest.PodmanNoCache([]string{"pull", "quay.io/libpod/testdigest_v2s2"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.PodmanNoCache([]string{"rmi", "busybox"})
+ session = podmanTest.PodmanNoCache([]string{"rmi", "testdigest_v2s2"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})
@@ -81,11 +81,11 @@ var _ = Describe("Podman pull", func() {
})
It("podman pull by digest", func() {
- session := podmanTest.PodmanNoCache([]string{"pull", "alpine@sha256:1072e499f3f655a032e88542330cf75b02e7bdf673278f701d7ba61629ee3ebe"})
+ session := podmanTest.PodmanNoCache([]string{"pull", "quay.io/libpod/testdigest_v2s2@sha256:755f4d90b3716e2bf57060d249e2cd61c9ac089b1233465c5c2cb2d7ee550fdb"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.PodmanNoCache([]string{"rmi", "alpine:none"})
+ session = podmanTest.PodmanNoCache([]string{"rmi", "testdigest_v2s2:none"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})
diff --git a/test/e2e/rmi_test.go b/test/e2e/rmi_test.go
index 7cb489113..cd62bf3b9 100644
--- a/test/e2e/rmi_test.go
+++ b/test/e2e/rmi_test.go
@@ -191,14 +191,14 @@ var _ = Describe("Podman rmi", func() {
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
- dockerfile := `FROM docker.io/library/alpine:latest
+ dockerfile := `FROM quay.io/libpod/alpine:latest
RUN mkdir hello
RUN touch test.txt
ENV foo=bar
`
podmanTest.BuildImage(dockerfile, "test", "true")
- dockerfile = `FROM docker.io/library/alpine:latest
+ dockerfile = `FROM quay.io/libpod/alpine:latest
RUN mkdir hello
RUN touch test.txt
RUN mkdir blah
@@ -256,7 +256,7 @@ var _ = Describe("Podman rmi", func() {
})
It("podman rmi -a with parent|child images", func() {
- dockerfile := `FROM docker.io/library/alpine:latest AS base
+ dockerfile := `FROM quay.io/libpod/alpine:latest AS base
RUN touch /1
ENV LOCAL=/1
RUN find $LOCAL
diff --git a/test/e2e/run_entrypoint_test.go b/test/e2e/run_entrypoint_test.go
index db802946e..2185d6b13 100644
--- a/test/e2e/run_entrypoint_test.go
+++ b/test/e2e/run_entrypoint_test.go
@@ -33,7 +33,7 @@ var _ = Describe("Podman run entrypoint", func() {
})
It("podman run no command, entrypoint, or cmd", func() {
- dockerfile := `FROM docker.io/library/alpine:latest
+ dockerfile := `FROM quay.io/libpod/alpine:latest
ENTRYPOINT []
CMD []
`
@@ -44,7 +44,7 @@ CMD []
})
It("podman run entrypoint", func() {
- dockerfile := `FROM docker.io/library/alpine:latest
+ dockerfile := `FROM quay.io/libpod/alpine:latest
ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
`
podmanTest.BuildImage(dockerfile, "foobar.com/entrypoint:latest", "false")
@@ -55,7 +55,7 @@ ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
})
It("podman run entrypoint with cmd", func() {
- dockerfile := `FROM docker.io/library/alpine:latest
+ dockerfile := `FROM quay.io/libpod/alpine:latest
CMD [ "-v"]
ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
`
@@ -67,7 +67,7 @@ ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
})
It("podman run entrypoint with user cmd overrides image cmd", func() {
- dockerfile := `FROM docker.io/library/alpine:latest
+ dockerfile := `FROM quay.io/libpod/alpine:latest
CMD [ "-v"]
ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
`
@@ -79,7 +79,7 @@ ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
})
It("podman run entrypoint with user cmd no image cmd", func() {
- dockerfile := `FROM docker.io/library/alpine:latest
+ dockerfile := `FROM quay.io/libpod/alpine:latest
ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
`
podmanTest.BuildImage(dockerfile, "foobar.com/entrypoint:latest", "false")
@@ -91,7 +91,7 @@ ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
It("podman run user entrypoint overrides image entrypoint and image cmd", func() {
SkipIfRemote("FIXME: podman-remote not handling passing --entrypoint=\"\" flag correctly")
- dockerfile := `FROM docker.io/library/alpine:latest
+ dockerfile := `FROM quay.io/libpod/alpine:latest
CMD ["-i"]
ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
`
@@ -108,7 +108,7 @@ ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
})
It("podman run user entrypoint with command overrides image entrypoint and image cmd", func() {
- dockerfile := `FROM docker.io/library/alpine:latest
+ dockerfile := `FROM quay.io/libpod/alpine:latest
CMD ["-i"]
ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
`
diff --git a/test/e2e/save_test.go b/test/e2e/save_test.go
index 79fc4d737..bdaef9259 100644
--- a/test/e2e/save_test.go
+++ b/test/e2e/save_test.go
@@ -134,7 +134,7 @@ var _ = Describe("Podman save", func() {
defer os.Setenv("GNUPGHOME", origGNUPGHOME)
port := 5000
- session := podmanTest.Podman([]string{"run", "-d", "--name", "registry", "-p", strings.Join([]string{strconv.Itoa(port), strconv.Itoa(port)}, ":"), "docker.io/registry:2.6"})
+ session := podmanTest.Podman([]string{"run", "-d", "--name", "registry", "-p", strings.Join([]string{strconv.Itoa(port), strconv.Itoa(port)}, ":"), "quay.io/libpod/registry:2.6"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
if !WaitContainerReady(podmanTest, "registry", "listening on", 20, 1) {
diff --git a/test/e2e/systemd_test.go b/test/e2e/systemd_test.go
index 218c250cd..48294943b 100644
--- a/test/e2e/systemd_test.go
+++ b/test/e2e/systemd_test.go
@@ -59,7 +59,7 @@ WantedBy=multi-user.target
Expect(stop.ExitCode()).To(Equal(0))
}()
- create := podmanTest.Podman([]string{"create", "--name", "redis", "redis"})
+ create := podmanTest.Podman([]string{"create", "--name", "redis", redis})
create.WaitWithDefaultTimeout()
Expect(create.ExitCode()).To(Equal(0))
diff --git a/test/e2e/tag_test.go b/test/e2e/tag_test.go
index 72d5cad77..3b43b0e20 100644
--- a/test/e2e/tag_test.go
+++ b/test/e2e/tag_test.go
@@ -41,7 +41,7 @@ var _ = Describe("Podman tag", func() {
results.WaitWithDefaultTimeout()
Expect(results.ExitCode()).To(Equal(0))
inspectData := results.InspectImageJSON()
- Expect(StringInSlice("docker.io/library/alpine:latest", inspectData[0].RepoTags)).To(BeTrue())
+ Expect(StringInSlice("quay.io/libpod/alpine:latest", inspectData[0].RepoTags)).To(BeTrue())
Expect(StringInSlice("localhost/foobar:latest", inspectData[0].RepoTags)).To(BeTrue())
})
@@ -54,7 +54,7 @@ var _ = Describe("Podman tag", func() {
results.WaitWithDefaultTimeout()
Expect(results.ExitCode()).To(Equal(0))
inspectData := results.InspectImageJSON()
- Expect(StringInSlice("docker.io/library/alpine:latest", inspectData[0].RepoTags)).To(BeTrue())
+ Expect(StringInSlice("quay.io/libpod/alpine:latest", inspectData[0].RepoTags)).To(BeTrue())
Expect(StringInSlice("localhost/foobar:latest", inspectData[0].RepoTags)).To(BeTrue())
})
@@ -67,7 +67,7 @@ var _ = Describe("Podman tag", func() {
results.WaitWithDefaultTimeout()
Expect(results.ExitCode()).To(Equal(0))
inspectData := results.InspectImageJSON()
- Expect(StringInSlice("docker.io/library/alpine:latest", inspectData[0].RepoTags)).To(BeTrue())
+ Expect(StringInSlice("quay.io/libpod/alpine:latest", inspectData[0].RepoTags)).To(BeTrue())
Expect(StringInSlice("localhost/foobar:new", inspectData[0].RepoTags)).To(BeTrue())
})
diff --git a/test/e2e/tree_test.go b/test/e2e/tree_test.go
index eeb00440c..22d53a8ea 100644
--- a/test/e2e/tree_test.go
+++ b/test/e2e/tree_test.go
@@ -35,7 +35,7 @@ var _ = Describe("Podman image tree", func() {
It("podman image tree", func() {
SkipIfRemote("Does not work on remote client")
- dockerfile := `FROM docker.io/library/busybox:latest
+ dockerfile := `FROM quay.io/libpod/busybox:latest
RUN mkdir hello
RUN touch test.txt
ENV foo=bar
@@ -45,14 +45,14 @@ ENV foo=bar
session := podmanTest.PodmanNoCache([]string{"image", "tree", "test:latest"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.PodmanNoCache([]string{"image", "tree", "--whatrequires", "docker.io/library/busybox:latest"})
+ session = podmanTest.PodmanNoCache([]string{"image", "tree", "--whatrequires", "quay.io/libpod/busybox:latest"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
session = podmanTest.PodmanNoCache([]string{"rmi", "test:latest"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session = podmanTest.PodmanNoCache([]string{"rmi", "docker.io/library/busybox:latest"})
+ session = podmanTest.PodmanNoCache([]string{"rmi", "quay.io/libpod/busybox:latest"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})
diff --git a/test/registries.conf b/test/registries.conf
index f27a282d6..0559c9e52 100644
--- a/test/registries.conf
+++ b/test/registries.conf
@@ -1,10 +1,17 @@
# Note that changing the order here may break tests.
-[registries.search]
-registries = ['docker.io', 'quay.io', 'registry.fedoraproject.org']
+unqualified-search-registries = ['docker.io', 'quay.io', 'registry.fedoraproject.org']
-[registries.insecure]
-registries = []
+[[registry]]
+# In Nov. 2020, Docker rate-limits image pulling. To avoid hitting these
+# limits while testing, always use the google mirror for qualified and
+# unqualified `docker.io` images.
+# Ref: https://cloud.google.com/container-registry/docs/pulling-cached-images
+prefix="docker.io"
+location="mirror.gcr.io"
-#blocked (docker only)
-[registries.block]
-registries = []
+# 2020-10-27 a number of images are not present in gcr.io, and podman
+# barfs spectacularly when trying to fetch them. We've hand-copied
+# those to quay, using skopeo copy --all ...
+[[registry]]
+prefix="docker.io/library"
+location="quay.io/libpod"
diff --git a/test/utils/utils.go b/test/utils/utils.go
index a45ce7b36..cb76d4a54 100644
--- a/test/utils/utils.go
+++ b/test/utils/utils.go
@@ -302,12 +302,7 @@ func (s *PodmanSession) LineInOutputContains(term string) bool {
// by podman-images(1).
func (s *PodmanSession) LineInOutputContainsTag(repo, tag string) bool {
tagMap := tagOutputToMap(s.OutputToStringArray())
- for r, t := range tagMap {
- if repo == r && tag == t {
- return true
- }
- }
- return false
+ return tagMap[repo][tag]
}
// IsJSONOutputValid attempts to unmarshal the session buffer
@@ -366,10 +361,11 @@ func StringInSlice(s string, sl []string) bool {
}
// tagOutPutToMap parses each string in imagesOutput and returns
-// a map of repo:tag pairs. Notice, the first array item will
+// a map whose key is a repo, and value is another map whose keys
+// are the tags found for that repo. Notice, the first array item will
// be skipped as it's considered to be the header.
-func tagOutputToMap(imagesOutput []string) map[string]string {
- m := make(map[string]string)
+func tagOutputToMap(imagesOutput []string) map[string]map[string]bool {
+ m := make(map[string]map[string]bool)
// iterate over output but skip the header
for _, i := range imagesOutput[1:] {
tmp := []string{}
@@ -383,7 +379,10 @@ func tagOutputToMap(imagesOutput []string) map[string]string {
if len(tmp) < 2 {
continue
}
- m[tmp[0]] = tmp[1]
+ if m[tmp[0]] == nil {
+ m[tmp[0]] = map[string]bool{}
+ }
+ m[tmp[0]][tmp[1]] = true
}
return m
}
diff --git a/vendor/golang.org/x/crypto/ssh/knownhosts/knownhosts.go b/vendor/golang.org/x/crypto/ssh/knownhosts/knownhosts.go
new file mode 100644
index 000000000..260cfe58c
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/knownhosts/knownhosts.go
@@ -0,0 +1,540 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package knownhosts implements a parser for the OpenSSH known_hosts
+// host key database, and provides utility functions for writing
+// OpenSSH compliant known_hosts files.
+package knownhosts
+
+import (
+ "bufio"
+ "bytes"
+ "crypto/hmac"
+ "crypto/rand"
+ "crypto/sha1"
+ "encoding/base64"
+ "errors"
+ "fmt"
+ "io"
+ "net"
+ "os"
+ "strings"
+
+ "golang.org/x/crypto/ssh"
+)
+
+// See the sshd manpage
+// (http://man.openbsd.org/sshd#SSH_KNOWN_HOSTS_FILE_FORMAT) for
+// background.
+
+type addr struct{ host, port string }
+
+func (a *addr) String() string {
+ h := a.host
+ if strings.Contains(h, ":") {
+ h = "[" + h + "]"
+ }
+ return h + ":" + a.port
+}
+
+type matcher interface {
+ match(addr) bool
+}
+
+type hostPattern struct {
+ negate bool
+ addr addr
+}
+
+func (p *hostPattern) String() string {
+ n := ""
+ if p.negate {
+ n = "!"
+ }
+
+ return n + p.addr.String()
+}
+
+type hostPatterns []hostPattern
+
+func (ps hostPatterns) match(a addr) bool {
+ matched := false
+ for _, p := range ps {
+ if !p.match(a) {
+ continue
+ }
+ if p.negate {
+ return false
+ }
+ matched = true
+ }
+ return matched
+}
+
+// See
+// https://android.googlesource.com/platform/external/openssh/+/ab28f5495c85297e7a597c1ba62e996416da7c7e/addrmatch.c
+// The matching of * has no regard for separators, unlike filesystem globs
+func wildcardMatch(pat []byte, str []byte) bool {
+ for {
+ if len(pat) == 0 {
+ return len(str) == 0
+ }
+ if len(str) == 0 {
+ return false
+ }
+
+ if pat[0] == '*' {
+ if len(pat) == 1 {
+ return true
+ }
+
+ for j := range str {
+ if wildcardMatch(pat[1:], str[j:]) {
+ return true
+ }
+ }
+ return false
+ }
+
+ if pat[0] == '?' || pat[0] == str[0] {
+ pat = pat[1:]
+ str = str[1:]
+ } else {
+ return false
+ }
+ }
+}
+
+func (p *hostPattern) match(a addr) bool {
+ return wildcardMatch([]byte(p.addr.host), []byte(a.host)) && p.addr.port == a.port
+}
+
+type keyDBLine struct {
+ cert bool
+ matcher matcher
+ knownKey KnownKey
+}
+
+func serialize(k ssh.PublicKey) string {
+ return k.Type() + " " + base64.StdEncoding.EncodeToString(k.Marshal())
+}
+
+func (l *keyDBLine) match(a addr) bool {
+ return l.matcher.match(a)
+}
+
+type hostKeyDB struct {
+ // Serialized version of revoked keys
+ revoked map[string]*KnownKey
+ lines []keyDBLine
+}
+
+func newHostKeyDB() *hostKeyDB {
+ db := &hostKeyDB{
+ revoked: make(map[string]*KnownKey),
+ }
+
+ return db
+}
+
+func keyEq(a, b ssh.PublicKey) bool {
+ return bytes.Equal(a.Marshal(), b.Marshal())
+}
+
+// IsAuthorityForHost can be used as a callback in ssh.CertChecker
+func (db *hostKeyDB) IsHostAuthority(remote ssh.PublicKey, address string) bool {
+ h, p, err := net.SplitHostPort(address)
+ if err != nil {
+ return false
+ }
+ a := addr{host: h, port: p}
+
+ for _, l := range db.lines {
+ if l.cert && keyEq(l.knownKey.Key, remote) && l.match(a) {
+ return true
+ }
+ }
+ return false
+}
+
+// IsRevoked can be used as a callback in ssh.CertChecker
+func (db *hostKeyDB) IsRevoked(key *ssh.Certificate) bool {
+ _, ok := db.revoked[string(key.Marshal())]
+ return ok
+}
+
+const markerCert = "@cert-authority"
+const markerRevoked = "@revoked"
+
+func nextWord(line []byte) (string, []byte) {
+ i := bytes.IndexAny(line, "\t ")
+ if i == -1 {
+ return string(line), nil
+ }
+
+ return string(line[:i]), bytes.TrimSpace(line[i:])
+}
+
+func parseLine(line []byte) (marker, host string, key ssh.PublicKey, err error) {
+ if w, next := nextWord(line); w == markerCert || w == markerRevoked {
+ marker = w
+ line = next
+ }
+
+ host, line = nextWord(line)
+ if len(line) == 0 {
+ return "", "", nil, errors.New("knownhosts: missing host pattern")
+ }
+
+ // ignore the keytype as it's in the key blob anyway.
+ _, line = nextWord(line)
+ if len(line) == 0 {
+ return "", "", nil, errors.New("knownhosts: missing key type pattern")
+ }
+
+ keyBlob, _ := nextWord(line)
+
+ keyBytes, err := base64.StdEncoding.DecodeString(keyBlob)
+ if err != nil {
+ return "", "", nil, err
+ }
+ key, err = ssh.ParsePublicKey(keyBytes)
+ if err != nil {
+ return "", "", nil, err
+ }
+
+ return marker, host, key, nil
+}
+
+func (db *hostKeyDB) parseLine(line []byte, filename string, linenum int) error {
+ marker, pattern, key, err := parseLine(line)
+ if err != nil {
+ return err
+ }
+
+ if marker == markerRevoked {
+ db.revoked[string(key.Marshal())] = &KnownKey{
+ Key: key,
+ Filename: filename,
+ Line: linenum,
+ }
+
+ return nil
+ }
+
+ entry := keyDBLine{
+ cert: marker == markerCert,
+ knownKey: KnownKey{
+ Filename: filename,
+ Line: linenum,
+ Key: key,
+ },
+ }
+
+ if pattern[0] == '|' {
+ entry.matcher, err = newHashedHost(pattern)
+ } else {
+ entry.matcher, err = newHostnameMatcher(pattern)
+ }
+
+ if err != nil {
+ return err
+ }
+
+ db.lines = append(db.lines, entry)
+ return nil
+}
+
+func newHostnameMatcher(pattern string) (matcher, error) {
+ var hps hostPatterns
+ for _, p := range strings.Split(pattern, ",") {
+ if len(p) == 0 {
+ continue
+ }
+
+ var a addr
+ var negate bool
+ if p[0] == '!' {
+ negate = true
+ p = p[1:]
+ }
+
+ if len(p) == 0 {
+ return nil, errors.New("knownhosts: negation without following hostname")
+ }
+
+ var err error
+ if p[0] == '[' {
+ a.host, a.port, err = net.SplitHostPort(p)
+ if err != nil {
+ return nil, err
+ }
+ } else {
+ a.host, a.port, err = net.SplitHostPort(p)
+ if err != nil {
+ a.host = p
+ a.port = "22"
+ }
+ }
+ hps = append(hps, hostPattern{
+ negate: negate,
+ addr: a,
+ })
+ }
+ return hps, nil
+}
+
+// KnownKey represents a key declared in a known_hosts file.
+type KnownKey struct {
+ Key ssh.PublicKey
+ Filename string
+ Line int
+}
+
+func (k *KnownKey) String() string {
+ return fmt.Sprintf("%s:%d: %s", k.Filename, k.Line, serialize(k.Key))
+}
+
+// KeyError is returned if we did not find the key in the host key
+// database, or there was a mismatch. Typically, in batch
+// applications, this should be interpreted as failure. Interactive
+// applications can offer an interactive prompt to the user.
+type KeyError struct {
+ // Want holds the accepted host keys. For each key algorithm,
+ // there can be one hostkey. If Want is empty, the host is
+ // unknown. If Want is non-empty, there was a mismatch, which
+ // can signify a MITM attack.
+ Want []KnownKey
+}
+
+func (u *KeyError) Error() string {
+ if len(u.Want) == 0 {
+ return "knownhosts: key is unknown"
+ }
+ return "knownhosts: key mismatch"
+}
+
+// RevokedError is returned if we found a key that was revoked.
+type RevokedError struct {
+ Revoked KnownKey
+}
+
+func (r *RevokedError) Error() string {
+ return "knownhosts: key is revoked"
+}
+
+// check checks a key against the host database. This should not be
+// used for verifying certificates.
+func (db *hostKeyDB) check(address string, remote net.Addr, remoteKey ssh.PublicKey) error {
+ if revoked := db.revoked[string(remoteKey.Marshal())]; revoked != nil {
+ return &RevokedError{Revoked: *revoked}
+ }
+
+ host, port, err := net.SplitHostPort(remote.String())
+ if err != nil {
+ return fmt.Errorf("knownhosts: SplitHostPort(%s): %v", remote, err)
+ }
+
+ hostToCheck := addr{host, port}
+ if address != "" {
+ // Give preference to the hostname if available.
+ host, port, err := net.SplitHostPort(address)
+ if err != nil {
+ return fmt.Errorf("knownhosts: SplitHostPort(%s): %v", address, err)
+ }
+
+ hostToCheck = addr{host, port}
+ }
+
+ return db.checkAddr(hostToCheck, remoteKey)
+}
+
+// checkAddr checks if we can find the given public key for the
+// given address. If we only find an entry for the IP address,
+// or only the hostname, then this still succeeds.
+func (db *hostKeyDB) checkAddr(a addr, remoteKey ssh.PublicKey) error {
+ // TODO(hanwen): are these the right semantics? What if there
+ // is just a key for the IP address, but not for the
+ // hostname?
+
+ // Algorithm => key.
+ knownKeys := map[string]KnownKey{}
+ for _, l := range db.lines {
+ if l.match(a) {
+ typ := l.knownKey.Key.Type()
+ if _, ok := knownKeys[typ]; !ok {
+ knownKeys[typ] = l.knownKey
+ }
+ }
+ }
+
+ keyErr := &KeyError{}
+ for _, v := range knownKeys {
+ keyErr.Want = append(keyErr.Want, v)
+ }
+
+ // Unknown remote host.
+ if len(knownKeys) == 0 {
+ return keyErr
+ }
+
+ // If the remote host starts using a different, unknown key type, we
+ // also interpret that as a mismatch.
+ if known, ok := knownKeys[remoteKey.Type()]; !ok || !keyEq(known.Key, remoteKey) {
+ return keyErr
+ }
+
+ return nil
+}
+
+// The Read function parses file contents.
+func (db *hostKeyDB) Read(r io.Reader, filename string) error {
+ scanner := bufio.NewScanner(r)
+
+ lineNum := 0
+ for scanner.Scan() {
+ lineNum++
+ line := scanner.Bytes()
+ line = bytes.TrimSpace(line)
+ if len(line) == 0 || line[0] == '#' {
+ continue
+ }
+
+ if err := db.parseLine(line, filename, lineNum); err != nil {
+ return fmt.Errorf("knownhosts: %s:%d: %v", filename, lineNum, err)
+ }
+ }
+ return scanner.Err()
+}
+
+// New creates a host key callback from the given OpenSSH host key
+// files. The returned callback is for use in
+// ssh.ClientConfig.HostKeyCallback. By preference, the key check
+// operates on the hostname if available, i.e. if a server changes its
+// IP address, the host key check will still succeed, even though a
+// record of the new IP address is not available.
+func New(files ...string) (ssh.HostKeyCallback, error) {
+ db := newHostKeyDB()
+ for _, fn := range files {
+ f, err := os.Open(fn)
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+ if err := db.Read(f, fn); err != nil {
+ return nil, err
+ }
+ }
+
+ var certChecker ssh.CertChecker
+ certChecker.IsHostAuthority = db.IsHostAuthority
+ certChecker.IsRevoked = db.IsRevoked
+ certChecker.HostKeyFallback = db.check
+
+ return certChecker.CheckHostKey, nil
+}
+
+// Normalize normalizes an address into the form used in known_hosts
+func Normalize(address string) string {
+ host, port, err := net.SplitHostPort(address)
+ if err != nil {
+ host = address
+ port = "22"
+ }
+ entry := host
+ if port != "22" {
+ entry = "[" + entry + "]:" + port
+ } else if strings.Contains(host, ":") && !strings.HasPrefix(host, "[") {
+ entry = "[" + entry + "]"
+ }
+ return entry
+}
+
+// Line returns a line to add append to the known_hosts files.
+func Line(addresses []string, key ssh.PublicKey) string {
+ var trimmed []string
+ for _, a := range addresses {
+ trimmed = append(trimmed, Normalize(a))
+ }
+
+ return strings.Join(trimmed, ",") + " " + serialize(key)
+}
+
+// HashHostname hashes the given hostname. The hostname is not
+// normalized before hashing.
+func HashHostname(hostname string) string {
+ // TODO(hanwen): check if we can safely normalize this always.
+ salt := make([]byte, sha1.Size)
+
+ _, err := rand.Read(salt)
+ if err != nil {
+ panic(fmt.Sprintf("crypto/rand failure %v", err))
+ }
+
+ hash := hashHost(hostname, salt)
+ return encodeHash(sha1HashType, salt, hash)
+}
+
+func decodeHash(encoded string) (hashType string, salt, hash []byte, err error) {
+ if len(encoded) == 0 || encoded[0] != '|' {
+ err = errors.New("knownhosts: hashed host must start with '|'")
+ return
+ }
+ components := strings.Split(encoded, "|")
+ if len(components) != 4 {
+ err = fmt.Errorf("knownhosts: got %d components, want 3", len(components))
+ return
+ }
+
+ hashType = components[1]
+ if salt, err = base64.StdEncoding.DecodeString(components[2]); err != nil {
+ return
+ }
+ if hash, err = base64.StdEncoding.DecodeString(components[3]); err != nil {
+ return
+ }
+ return
+}
+
+func encodeHash(typ string, salt []byte, hash []byte) string {
+ return strings.Join([]string{"",
+ typ,
+ base64.StdEncoding.EncodeToString(salt),
+ base64.StdEncoding.EncodeToString(hash),
+ }, "|")
+}
+
+// See https://android.googlesource.com/platform/external/openssh/+/ab28f5495c85297e7a597c1ba62e996416da7c7e/hostfile.c#120
+func hashHost(hostname string, salt []byte) []byte {
+ mac := hmac.New(sha1.New, salt)
+ mac.Write([]byte(hostname))
+ return mac.Sum(nil)
+}
+
+type hashedHost struct {
+ salt []byte
+ hash []byte
+}
+
+const sha1HashType = "1"
+
+func newHashedHost(encoded string) (*hashedHost, error) {
+ typ, salt, hash, err := decodeHash(encoded)
+ if err != nil {
+ return nil, err
+ }
+
+ // The type field seems for future algorithm agility, but it's
+ // actually hardcoded in openssh currently, see
+ // https://android.googlesource.com/platform/external/openssh/+/ab28f5495c85297e7a597c1ba62e996416da7c7e/hostfile.c#120
+ if typ != sha1HashType {
+ return nil, fmt.Errorf("knownhosts: got hash type %s, must be '1'", typ)
+ }
+
+ return &hashedHost{salt: salt, hash: hash}, nil
+}
+
+func (h *hashedHost) match(a addr) bool {
+ return bytes.Equal(hashHost(Normalize(a.String()), h.salt), h.hash)
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 4e81d5f02..4ed3bbcda 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -591,6 +591,7 @@ golang.org/x/crypto/poly1305
golang.org/x/crypto/ssh
golang.org/x/crypto/ssh/agent
golang.org/x/crypto/ssh/internal/bcrypt_pbkdf
+golang.org/x/crypto/ssh/knownhosts
golang.org/x/crypto/ssh/terminal
# golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0
golang.org/x/net/context