Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug 1920205: use secure local registry for e2e tests #552

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
35 changes: 32 additions & 3 deletions .github/workflows/test.yml
Expand Up @@ -28,7 +28,8 @@ jobs:
steps:
- uses: actions/checkout@v2
- run: |
sudo apt-get -y install conntrack
sudo apt-get -y update
sudo apt-get -y install conntrack podman
curl -sLo minikube "$(curl -sL https://api.github.com/repos/kubernetes/minikube/releases/latest | jq -r '[.assets[] | select(.name == "minikube-linux-amd64")] | first | .browser_download_url')"
chmod +x minikube
sudo mv minikube /bin/
Expand All @@ -38,12 +39,27 @@ jobs:
sudo usermod -aG docker "$USER"
eval $(minikube docker-env)
- run: |
KUBECONFIG="$HOME/.kube/config" make build e2e
mkdir -p certs
openssl req -x509 -newkey rsa:4096 -keyout certs/key.pem -out certs/cert.pem -days 365 -subj '/CN=localhost' -nodes -addext 'subjectAltName = DNS:localhost'
docker run -d --restart=always --name registry -v "$(pwd)"/certs:/certs -e REGISTRY_HTTP_ADDR=0.0.0.0:443 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/cert.pem \
-e REGISTRY_HTTP_TLS_KEY=/certs/key.pem \
-p 443:443 \
registry:2
sudo mkdir /etc/docker/certs.d
sudo mkdir /etc/docker/certs.d/localhost:443
sudo cp certs/cert.pem /etc/docker/certs.d/localhost:443/ca.crt
sudo cp certs/cert.pem /usr/local/share/ca-certificates/ca.crt
sudo update-ca-certificates
export DOCKER_REGISTRY_HOST=localhost:443
- run: |
KUBECONFIG="$HOME/.kube/config" DOCKER_REGISTRY_HOST=localhost:443 make build e2e
e2e-kind:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: |
sudo apt-get -y update
sudo apt-get -y install podman
curl -sLo kind "$(curl -sL https://api.github.com/repos/kubernetes-sigs/kind/releases/latest | jq -r '[.assets[] | select(.name == "kind-linux-amd64")] | first | .browser_download_url')"
chmod +x kind
sudo mv kind /bin/
Expand All @@ -53,4 +69,17 @@ jobs:
sudo chown -R "$USER" "$HOME/.kube"
sudo usermod -aG docker "$USER"
- run: |
KUBECONFIG="$HOME/.kube/config" make build e2e
mkdir -p certs
openssl req -x509 -newkey rsa:4096 -keyout certs/key.pem -out certs/cert.pem -days 365 -subj '/CN=localhost' -nodes -addext 'subjectAltName = DNS:localhost'
docker run -d --restart=always --name registry -v "$(pwd)"/certs:/certs -e REGISTRY_HTTP_ADDR=0.0.0.0:443 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/cert.pem \
-e REGISTRY_HTTP_TLS_KEY=/certs/key.pem \
-p 443:443 \
registry:2
sudo mkdir /etc/docker/certs.d
sudo mkdir /etc/docker/certs.d/localhost:443
sudo cp certs/cert.pem /etc/docker/certs.d/localhost:443/ca.crt
sudo cp certs/cert.pem /usr/local/share/ca-certificates/ca.crt
sudo update-ca-certificates
export DOCKER_REGISTRY_HOST=localhost:443
- run: |
KUBECONFIG="$HOME/.kube/config" DOCKER_REGISTRY_HOST=localhost:443 make build e2e
3 changes: 1 addition & 2 deletions pkg/image/containerdregistry/resolver.go
Expand Up @@ -40,8 +40,7 @@ func NewResolver(configDir string, insecure bool, roots *x509.CertPool) (remotes
headers := http.Header{}
headers.Set("User-Agent", "opm/alpha")

client := http.DefaultClient
client.Transport = transport
client := &http.Client{Transport: transport}

cfg, err := loadConfig(configDir)
if err != nil {
Expand Down
29 changes: 23 additions & 6 deletions test/e2e/e2e_suite_test.go
@@ -1,6 +1,7 @@
package e2e_test

import (
"fmt"
"os"
"os/exec"
"testing"
Expand All @@ -9,9 +10,14 @@ import (
. "github.com/onsi/gomega"
)

// quay.io is the default registry used if no local registry endpoint is provided
// Note: login credentials are required to push/pull to quay
const defaultRegistry = "quay.io"

var (
dockerUsername = os.Getenv("DOCKER_USERNAME")
dockerPassword = os.Getenv("DOCKER_PASSWORD")
dockerHost = os.Getenv("DOCKER_REGISTRY_HOST") // 'DOCKER_HOST' is reserved for the docker daemon
)

func TestE2E(t *testing.T) {
Expand All @@ -20,13 +26,24 @@ func TestE2E(t *testing.T) {
}

var _ = BeforeSuite(func() {
// FIXME: Since podman login doesn't work with daemonless image pulling, we need to login with docker first so podman tests don't fail.
if dockerUsername == "" || dockerPassword == "" {
// Test will be skipped anyway
switch {
case dockerUsername == "" && dockerPassword == "" && dockerHost == "":
// No registry credentials or local registry host provided
// Fail early
GinkgoT().Fatal("No registry credentials or local registry host provided")
case dockerHost != "" && dockerUsername == "" && dockerPassword == "":
// Running against local secure registry without credentials
// No need to login
return
case dockerHost == "" && dockerUsername != "" && dockerPassword != "":
// Set host to default registry
dockerHost = defaultRegistry
}

dockerlogin := exec.Command("docker", "login", "-u", dockerUsername, "-p", dockerPassword, "quay.io")
err := dockerlogin.Run()
Expect(err).NotTo(HaveOccurred(), "Error logging into quay.io")
// FIXME: Since podman login doesn't work with daemonless image pulling, we need to login with docker first so podman tests don't fail.
dockerlogin := exec.Command("docker", "login", "-u", dockerUsername, "-p", dockerPassword, dockerHost)
Expect(dockerlogin.Run()).To(Succeed(), "Error logging into %s", dockerHost)

By(fmt.Sprintf("Using container image registry %s", dockerHost))
})

59 changes: 24 additions & 35 deletions test/e2e/opm_test.go
Expand Up @@ -41,10 +41,11 @@ var (
indexTag2 = rand.String(6)
indexTag3 = rand.String(6)

bundleImage = "quay.io/olmtest/e2e-bundle"
indexImage1 = "quay.io/olmtest/e2e-index:" + indexTag1
indexImage2 = "quay.io/olmtest/e2e-index:" + indexTag2
indexImage3 = "quay.io/olmtest/e2e-index:" + indexTag3
bundleImage = dockerHost + "/olmtest/e2e-bundle"
indexImage = dockerHost + "/olmtest/e2e-index"
indexImage1 = dockerHost + "/olmtest/e2e-index:" + indexTag1
indexImage2 = dockerHost + "/olmtest/e2e-index:" + indexTag2
indexImage3 = dockerHost + "/olmtest/e2e-index:" + indexTag3
)

type bundleLocation struct {
Expand Down Expand Up @@ -147,6 +148,8 @@ func pruneIndexWith(containerTool string) error {

func pushWith(containerTool, image string) error {
dockerpush := exec.Command(containerTool, "push", image)
dockerpush.Stderr = GinkgoWriter
dockerpush.Stdout = GinkgoWriter
return dockerpush.Run()
}

Expand Down Expand Up @@ -207,16 +210,6 @@ func initialize() error {

var _ = Describe("opm", func() {
IncludeSharedSpecs := func(containerTool string) {
BeforeEach(func() {
if dockerUsername == "" || dockerPassword == "" {
Skip("registry credentials are not available")
}

dockerlogin := exec.Command(containerTool, "login", "-u", dockerUsername, "-p", dockerPassword, "quay.io")
err := dockerlogin.Run()
Expect(err).NotTo(HaveOccurred(), "Error logging into quay.io")
})

It("builds and validates a bundle image", func() {
By("building bundle")
img := bundleImage + ":" + bundleTag3
Expand Down Expand Up @@ -259,9 +252,9 @@ var _ = Describe("opm", func() {
It("builds and manipulates bundle and index images", func() {
By("building bundles")
bundles := bundleLocations{
{bundleTag1, bundlePath1},
{bundleTag2, bundlePath2},
{bundleTag3, bundlePath3},
{bundleImage + ":" + bundleTag1, bundlePath1},
{bundleImage + ":" + bundleTag2, bundlePath2},
{bundleImage + ":" + bundleTag3, bundlePath3},
}
var err error
for _, b := range bundles {
Expand Down Expand Up @@ -359,31 +352,19 @@ var _ = Describe("opm", func() {
}

By("building an index")
indexImage := "quay.io/olmtest/e2e-index:" + rand.String(6)
indexImage := indexImage + ":" + rand.String(6)
err := buildIndexWith(containerTool, "", indexImage, bundles.images(), registry.ReplacesMode, false)
Expect(err).NotTo(HaveOccurred())

workingDir, err := os.Getwd()
Expect(err).NotTo(HaveOccurred())
err = os.Remove(workingDir + "/" + bundle.DockerFile)
Expect(err).NotTo(HaveOccurred())
})
It("build index without bundles", func() {

indexImage := "quay.io/olmtest/e2e-index:" + rand.String(6)

indexImage := indexImage + ":" + rand.String(6)
By("building an index")
err := buildIndexWith(containerTool, indexImage, "", []string{}, registry.ReplacesMode, true)
Expect(err).NotTo(HaveOccurred())

workingDir, err := os.Getwd()
Expect(err).NotTo(HaveOccurred())
err = os.Remove(workingDir + "/" + bundle.DockerFile)
err := buildIndexWith(containerTool, "", indexImage, []string{}, registry.ReplacesMode, true)
Expect(err).NotTo(HaveOccurred())
})

It("can overwrite existing bundles in an index", func() {

PIt("can overwrite existing bundles in an index", func() {
exdx marked this conversation as resolved.
Show resolved Hide resolved
// TODO fix regression overwriting existing bundles in an index
bundles := bundleLocations{
{bundleImage + ":" + rand.String(6), "./testdata/aqua/0.0.1"},
{bundleImage + ":" + rand.String(6), "./testdata/aqua/0.0.2"},
Expand All @@ -406,7 +387,7 @@ var _ = Describe("opm", func() {
Expect(pushWith(containerTool, b.image)).NotTo(HaveOccurred())
}

indexImage := "quay.io/olmtest/e2e-index:" + rand.String(6)
indexImage := indexImage + ":" + rand.String(6)
By("adding net-new bundles to an index")
err := buildIndexWith(containerTool, "", indexImage, bundles[:4].images(), registry.ReplacesMode, true) // 0.0.1, 0.0.2, 1.0.0, 1.0.1
Expect(err).NotTo(HaveOccurred())
Expand All @@ -428,10 +409,18 @@ var _ = Describe("opm", func() {
}

Context("using docker", func() {
if err := exec.Command("docker").Run(); err != nil {
GinkgoT().Logf("container tool docker not found - skipping docker-based opm e2e tests: %s", err)
return
}
IncludeSharedSpecs("docker")
})

Context("using podman", func() {
if err := exec.Command("podman", "info").Run(); err != nil {
GinkgoT().Log("container tool podman not found - skipping podman-based opm e2e tests: %s", err)
return
}
IncludeSharedSpecs("podman")
})
})