github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/test/e2e/search_test.go (about)

     1  // +build !remoteclient
     2  
     3  package integration
     4  
     5  import (
     6  	"bytes"
     7  	"fmt"
     8  	"io/ioutil"
     9  	"os"
    10  	"strconv"
    11  	"text/template"
    12  
    13  	. "github.com/containers/libpod/test/utils"
    14  	. "github.com/onsi/ginkgo"
    15  	. "github.com/onsi/gomega"
    16  )
    17  
    18  type endpoint struct {
    19  	Host string
    20  	Port string
    21  }
    22  
    23  func (e *endpoint) Address() string {
    24  	return fmt.Sprintf("%s:%s", e.Host, e.Port)
    25  }
    26  
    27  var _ = Describe("Podman search", func() {
    28  	var (
    29  		tempdir    string
    30  		err        error
    31  		podmanTest *PodmanTestIntegration
    32  	)
    33  
    34  	var registryEndpoints = []endpoint{
    35  		{"localhost", "5001"},
    36  		{"localhost", "5002"},
    37  		{"localhost", "5003"},
    38  		{"localhost", "5004"},
    39  		{"localhost", "5005"},
    40  		{"localhost", "5006"},
    41  		{"localhost", "5007"},
    42  		{"localhost", "5008"},
    43  		{"localhost", "5009"},
    44  	}
    45  
    46  	const regFileContents = `
    47  [registries.search]
    48  registries = ['{{.Host}}:{{.Port}}']
    49  
    50  [registries.insecure]
    51  registries = ['{{.Host}}:{{.Port}}']`
    52  	registryFileTmpl := template.Must(template.New("registryFile").Parse(regFileContents))
    53  
    54  	const badRegFileContents = `
    55  [registries.search]
    56  registries = ['{{.Host}}:{{.Port}}']
    57  # empty
    58  [registries.insecure]
    59  registries = []`
    60  	registryFileBadTmpl := template.Must(template.New("registryFileBad").Parse(badRegFileContents))
    61  
    62  	const regFileContents2 = `
    63  [registries.search]
    64  registries = ['{{.Host}}:{{.Port}}', '{{.Host}}:6000']
    65  
    66  [registries.insecure]
    67  registries = ['{{.Host}}:{{.Port}}']`
    68  	registryFileTwoTmpl := template.Must(template.New("registryFileTwo").Parse(regFileContents2))
    69  
    70  	BeforeEach(func() {
    71  		tempdir, err = CreateTempDirInTempDir()
    72  		if err != nil {
    73  			os.Exit(1)
    74  		}
    75  
    76  		podmanTest = PodmanTestCreate(tempdir)
    77  		podmanTest.Setup()
    78  		podmanTest.SeedImages()
    79  
    80  	})
    81  
    82  	AfterEach(func() {
    83  		podmanTest.Cleanup()
    84  		f := CurrentGinkgoTestDescription()
    85  		processTestResult(f)
    86  	})
    87  
    88  	It("podman search", func() {
    89  		search := podmanTest.Podman([]string{"search", "alpine"})
    90  		search.WaitWithDefaultTimeout()
    91  		Expect(search.ExitCode()).To(Equal(0))
    92  		Expect(len(search.OutputToStringArray())).To(BeNumerically(">", 1))
    93  		Expect(search.LineInOutputContains("docker.io/library/alpine")).To(BeTrue())
    94  	})
    95  
    96  	It("podman search single registry flag", func() {
    97  		search := podmanTest.Podman([]string{"search", "quay.io/libpod/gate:latest"})
    98  		search.WaitWithDefaultTimeout()
    99  		Expect(search.ExitCode()).To(Equal(0))
   100  		Expect(search.LineInOutputContains("quay.io/libpod/gate")).To(BeTrue())
   101  	})
   102  
   103  	It("podman search format flag", func() {
   104  		search := podmanTest.Podman([]string{"search", "--format", "table {{.Index}} {{.Name}}", "alpine"})
   105  		search.WaitWithDefaultTimeout()
   106  		Expect(search.ExitCode()).To(Equal(0))
   107  		Expect(len(search.OutputToStringArray())).To(BeNumerically(">", 1))
   108  		Expect(search.LineInOutputContains("docker.io/library/alpine")).To(BeTrue())
   109  	})
   110  
   111  	It("podman search no-trunc flag", func() {
   112  		search := podmanTest.Podman([]string{"search", "--no-trunc", "alpine"})
   113  		search.WaitWithDefaultTimeout()
   114  		Expect(search.ExitCode()).To(Equal(0))
   115  		Expect(len(search.OutputToStringArray())).To(BeNumerically(">", 1))
   116  		Expect(search.LineInOutputContains("docker.io/library/alpine")).To(BeTrue())
   117  		Expect(search.LineInOutputContains("...")).To(BeFalse())
   118  	})
   119  
   120  	It("podman search limit flag", func() {
   121  		search := podmanTest.Podman([]string{"search", "docker.io/alpine"})
   122  		search.WaitWithDefaultTimeout()
   123  		Expect(search.ExitCode()).To(Equal(0))
   124  		Expect(len(search.OutputToStringArray())).To(Equal(26))
   125  
   126  		search = podmanTest.Podman([]string{"search", "--limit", "3", "docker.io/alpine"})
   127  		search.WaitWithDefaultTimeout()
   128  		Expect(search.ExitCode()).To(Equal(0))
   129  		Expect(len(search.OutputToStringArray())).To(Equal(4))
   130  
   131  		search = podmanTest.Podman([]string{"search", "--limit", "30", "docker.io/alpine"})
   132  		search.WaitWithDefaultTimeout()
   133  		Expect(search.ExitCode()).To(Equal(0))
   134  		Expect(len(search.OutputToStringArray())).To(Equal(31))
   135  	})
   136  
   137  	It("podman search with filter stars", func() {
   138  		search := podmanTest.Podman([]string{"search", "--filter", "stars=10", "--format", "{{.Stars}}", "alpine"})
   139  		search.WaitWithDefaultTimeout()
   140  		Expect(search.ExitCode()).To(Equal(0))
   141  		output := search.OutputToStringArray()
   142  		for i := 0; i < len(output); i++ {
   143  			Expect(strconv.Atoi(output[i])).To(BeNumerically(">=", 10))
   144  		}
   145  	})
   146  
   147  	It("podman search with filter is-official", func() {
   148  		search := podmanTest.Podman([]string{"search", "--filter", "is-official", "--format", "{{.Official}}", "alpine"})
   149  		search.WaitWithDefaultTimeout()
   150  		Expect(search.ExitCode()).To(Equal(0))
   151  		output := search.OutputToStringArray()
   152  		for i := 0; i < len(output); i++ {
   153  			Expect(output[i]).To(Equal("[OK]"))
   154  		}
   155  	})
   156  
   157  	It("podman search with filter is-automated", func() {
   158  		search := podmanTest.Podman([]string{"search", "--filter", "is-automated=false", "--format", "{{.Automated}}", "alpine"})
   159  		search.WaitWithDefaultTimeout()
   160  		Expect(search.ExitCode()).To(Equal(0))
   161  		output := search.OutputToStringArray()
   162  		for i := 0; i < len(output); i++ {
   163  			Expect(output[i]).To(Equal(""))
   164  		}
   165  	})
   166  
   167  	It("podman search attempts HTTP if tls-verify flag is set false", func() {
   168  		if podmanTest.Host.Arch == "ppc64le" {
   169  			Skip("No registry image for ppc64le")
   170  		}
   171  		lock := GetPortLock(registryEndpoints[0].Port)
   172  		defer lock.Unlock()
   173  
   174  		fakereg := podmanTest.Podman([]string{"run", "-d", "--name", "registry",
   175  			"-p", fmt.Sprintf("%s:5000", registryEndpoints[0].Port),
   176  			registry, "/entrypoint.sh", "/etc/docker/registry/config.yml"})
   177  		fakereg.WaitWithDefaultTimeout()
   178  		Expect(fakereg.ExitCode()).To(Equal(0))
   179  
   180  		if !WaitContainerReady(podmanTest, "registry", "listening on", 20, 1) {
   181  			Skip("Can not start docker registry.")
   182  		}
   183  
   184  		search := podmanTest.Podman([]string{"search",
   185  			fmt.Sprintf("%s/fake/image:andtag", registryEndpoints[0].Address()), "--tls-verify=false"})
   186  		search.WaitWithDefaultTimeout()
   187  
   188  		// if this test succeeded, there will be no output (there is no entry named fake/image:andtag in an empty registry)
   189  		// and the exit code will be 0
   190  		Expect(search.ExitCode()).To(Equal(0))
   191  		Expect(search.OutputToString()).Should(BeEmpty())
   192  		Expect(search.ErrorToString()).Should(BeEmpty())
   193  	})
   194  
   195  	It("podman search in local registry", func() {
   196  		if podmanTest.Host.Arch == "ppc64le" {
   197  			Skip("No registry image for ppc64le")
   198  		}
   199  		lock := GetPortLock(registryEndpoints[3].Port)
   200  		defer lock.Unlock()
   201  		registry := podmanTest.Podman([]string{"run", "-d", "--name", "registry3",
   202  			"-p", fmt.Sprintf("%s:5000", registryEndpoints[3].Port), registry,
   203  			"/entrypoint.sh", "/etc/docker/registry/config.yml"})
   204  		registry.WaitWithDefaultTimeout()
   205  		Expect(registry.ExitCode()).To(Equal(0))
   206  
   207  		if !WaitContainerReady(podmanTest, "registry3", "listening on", 20, 1) {
   208  			Skip("Can not start docker registry.")
   209  		}
   210  
   211  		podmanTest.RestoreArtifact(ALPINE)
   212  		image := fmt.Sprintf("%s/my-alpine", registryEndpoints[3].Address())
   213  		push := podmanTest.PodmanNoCache([]string{"push", "--tls-verify=false", "--remove-signatures", ALPINE, image})
   214  		push.WaitWithDefaultTimeout()
   215  		Expect(push.ExitCode()).To(Equal(0))
   216  		search := podmanTest.PodmanNoCache([]string{"search", image, "--tls-verify=false"})
   217  		search.WaitWithDefaultTimeout()
   218  
   219  		Expect(search.ExitCode()).To(Equal(0))
   220  		Expect(search.OutputToString()).ShouldNot(BeEmpty())
   221  
   222  		// podman search v2 registry with empty query
   223  		searchEmpty := podmanTest.PodmanNoCache([]string{"search", fmt.Sprintf("%s/", registryEndpoints[3].Address()), "--tls-verify=false"})
   224  		searchEmpty.WaitWithDefaultTimeout()
   225  		Expect(searchEmpty.ExitCode()).To(BeZero())
   226  		Expect(len(searchEmpty.OutputToStringArray())).To(BeNumerically(">=", 1))
   227  		match, _ := search.GrepString("my-alpine")
   228  		Expect(match).Should(BeTrue())
   229  	})
   230  
   231  	It("podman search attempts HTTP if registry is in registries.insecure and force secure is false", func() {
   232  		if podmanTest.Host.Arch == "ppc64le" {
   233  			Skip("No registry image for ppc64le")
   234  		}
   235  
   236  		lock := GetPortLock(registryEndpoints[4].Port)
   237  		defer lock.Unlock()
   238  		registry := podmanTest.Podman([]string{"run", "-d", "-p", fmt.Sprintf("%s:5000", registryEndpoints[4].Port),
   239  			"--name", "registry4", registry, "/entrypoint.sh", "/etc/docker/registry/config.yml"})
   240  		registry.WaitWithDefaultTimeout()
   241  		Expect(registry.ExitCode()).To(Equal(0))
   242  
   243  		if !WaitContainerReady(podmanTest, "registry4", "listening on", 20, 1) {
   244  			Skip("Can not start docker registry.")
   245  		}
   246  
   247  		podmanTest.RestoreArtifact(ALPINE)
   248  		image := fmt.Sprintf("%s/my-alpine", registryEndpoints[4].Address())
   249  		push := podmanTest.PodmanNoCache([]string{"push", "--tls-verify=false", "--remove-signatures", ALPINE, image})
   250  		push.WaitWithDefaultTimeout()
   251  		Expect(push.ExitCode()).To(Equal(0))
   252  
   253  		// registries.conf set up
   254  		var buffer bytes.Buffer
   255  		registryFileTmpl.Execute(&buffer, registryEndpoints[4])
   256  		podmanTest.setRegistriesConfigEnv(buffer.Bytes())
   257  		ioutil.WriteFile(fmt.Sprintf("%s/registry4.conf", tempdir), buffer.Bytes(), 0644)
   258  
   259  		search := podmanTest.PodmanNoCache([]string{"search", image})
   260  		search.WaitWithDefaultTimeout()
   261  
   262  		Expect(search.ExitCode()).To(Equal(0))
   263  		match, _ := search.GrepString("my-alpine")
   264  		Expect(match).Should(BeTrue())
   265  		Expect(search.ErrorToString()).Should(BeEmpty())
   266  
   267  		// cleanup
   268  		resetRegistriesConfigEnv()
   269  	})
   270  
   271  	It("podman search doesn't attempt HTTP if force secure is true", func() {
   272  		if podmanTest.Host.Arch == "ppc64le" {
   273  			Skip("No registry image for ppc64le")
   274  		}
   275  		lock := GetPortLock(registryEndpoints[5].Port)
   276  		defer lock.Unlock()
   277  		registry := podmanTest.Podman([]string{"run", "-d", "-p", fmt.Sprintf("%s:5000", registryEndpoints[5].Port),
   278  			"--name", "registry5", registry})
   279  		registry.WaitWithDefaultTimeout()
   280  		Expect(registry.ExitCode()).To(Equal(0))
   281  
   282  		if !WaitContainerReady(podmanTest, "registry5", "listening on", 20, 1) {
   283  			Skip("Can not start docker registry.")
   284  		}
   285  
   286  		podmanTest.RestoreArtifact(ALPINE)
   287  		image := fmt.Sprintf("%s/my-alpine", registryEndpoints[5].Address())
   288  		push := podmanTest.PodmanNoCache([]string{"push", "--tls-verify=false", "--remove-signatures", ALPINE, image})
   289  		push.WaitWithDefaultTimeout()
   290  		Expect(push.ExitCode()).To(Equal(0))
   291  
   292  		var buffer bytes.Buffer
   293  		registryFileTmpl.Execute(&buffer, registryEndpoints[5])
   294  		podmanTest.setRegistriesConfigEnv(buffer.Bytes())
   295  		ioutil.WriteFile(fmt.Sprintf("%s/registry5.conf", tempdir), buffer.Bytes(), 0644)
   296  
   297  		search := podmanTest.PodmanNoCache([]string{"search", image, "--tls-verify=true"})
   298  		search.WaitWithDefaultTimeout()
   299  
   300  		Expect(search.ExitCode()).To(Equal(0))
   301  		Expect(search.OutputToString()).Should(BeEmpty())
   302  		match, _ := search.ErrorGrepString("error")
   303  		Expect(match).Should(BeTrue())
   304  
   305  		// cleanup
   306  		resetRegistriesConfigEnv()
   307  	})
   308  
   309  	It("podman search doesn't attempt HTTP if registry is not listed as insecure", func() {
   310  		if podmanTest.Host.Arch == "ppc64le" {
   311  			Skip("No registry image for ppc64le")
   312  		}
   313  		lock := GetPortLock(registryEndpoints[6].Port)
   314  		defer lock.Unlock()
   315  		registry := podmanTest.Podman([]string{"run", "-d", "-p", fmt.Sprintf("%s:5000", registryEndpoints[6].Port),
   316  			"--name", "registry6", registry})
   317  		registry.WaitWithDefaultTimeout()
   318  		Expect(registry.ExitCode()).To(Equal(0))
   319  
   320  		if !WaitContainerReady(podmanTest, "registry6", "listening on", 20, 1) {
   321  			Skip("Can not start docker registry.")
   322  		}
   323  
   324  		podmanTest.RestoreArtifact(ALPINE)
   325  		image := fmt.Sprintf("%s/my-alpine", registryEndpoints[6].Address())
   326  		push := podmanTest.PodmanNoCache([]string{"push", "--tls-verify=false", "--remove-signatures", ALPINE, image})
   327  		push.WaitWithDefaultTimeout()
   328  		Expect(push.ExitCode()).To(Equal(0))
   329  
   330  		var buffer bytes.Buffer
   331  		registryFileBadTmpl.Execute(&buffer, registryEndpoints[6])
   332  		podmanTest.setRegistriesConfigEnv(buffer.Bytes())
   333  		ioutil.WriteFile(fmt.Sprintf("%s/registry6.conf", tempdir), buffer.Bytes(), 0644)
   334  
   335  		search := podmanTest.PodmanNoCache([]string{"search", image})
   336  		search.WaitWithDefaultTimeout()
   337  
   338  		Expect(search.ExitCode()).To(Equal(0))
   339  		Expect(search.OutputToString()).Should(BeEmpty())
   340  		match, _ := search.ErrorGrepString("error")
   341  		Expect(match).Should(BeTrue())
   342  
   343  		// cleanup
   344  		resetRegistriesConfigEnv()
   345  	})
   346  
   347  	It("podman search doesn't attempt HTTP if one registry is not listed as insecure", func() {
   348  		if podmanTest.Host.Arch == "ppc64le" {
   349  			Skip("No registry image for ppc64le")
   350  		}
   351  		lock7 := GetPortLock(registryEndpoints[7].Port)
   352  		defer lock7.Unlock()
   353  		lock8 := GetPortLock("6000")
   354  		defer lock8.Unlock()
   355  
   356  		registryLocal := podmanTest.Podman([]string{"run", "-d", "--net=host", "-p", fmt.Sprintf("%s:5000", registryEndpoints[7].Port),
   357  			"--name", "registry7", registry})
   358  		registryLocal.WaitWithDefaultTimeout()
   359  		Expect(registryLocal.ExitCode()).To(Equal(0))
   360  
   361  		if !WaitContainerReady(podmanTest, "registry7", "listening on", 20, 1) {
   362  			Skip("Can not start docker registry.")
   363  		}
   364  
   365  		registryLocal = podmanTest.Podman([]string{"run", "-d", "-p", "6000:5000", "--name", "registry8", registry})
   366  		registryLocal.WaitWithDefaultTimeout()
   367  		Expect(registryLocal.ExitCode()).To(Equal(0))
   368  
   369  		if !WaitContainerReady(podmanTest, "registry8", "listening on", 20, 1) {
   370  			Skip("Can not start docker registry.")
   371  		}
   372  
   373  		podmanTest.RestoreArtifact(ALPINE)
   374  		push := podmanTest.PodmanNoCache([]string{"push", "--tls-verify=false", "--remove-signatures", ALPINE, "localhost:6000/my-alpine"})
   375  		push.WaitWithDefaultTimeout()
   376  		Expect(push.ExitCode()).To(Equal(0))
   377  
   378  		// registries.conf set up
   379  		var buffer bytes.Buffer
   380  		registryFileTwoTmpl.Execute(&buffer, registryEndpoints[8])
   381  		podmanTest.setRegistriesConfigEnv(buffer.Bytes())
   382  		ioutil.WriteFile(fmt.Sprintf("%s/registry8.conf", tempdir), buffer.Bytes(), 0644)
   383  
   384  		search := podmanTest.PodmanNoCache([]string{"search", "my-alpine"})
   385  		search.WaitWithDefaultTimeout()
   386  
   387  		Expect(search.ExitCode()).To(Equal(0))
   388  		Expect(search.OutputToString()).Should(BeEmpty())
   389  		match, _ := search.ErrorGrepString("error")
   390  		Expect(match).Should(BeTrue())
   391  
   392  		// cleanup
   393  		resetRegistriesConfigEnv()
   394  	})
   395  
   396  	// search should fail with nonexist authfile
   397  	It("podman search fail with nonexist --authfile", func() {
   398  		SkipIfRemote()
   399  		search := podmanTest.Podman([]string{"search", "--authfile", "/tmp/nonexist", ALPINE})
   400  		search.WaitWithDefaultTimeout()
   401  		Expect(search.ExitCode()).To(Not(Equal(0)))
   402  	})
   403  })