search.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. package daemon
  2. import (
  3. "strconv"
  4. "golang.org/x/net/context"
  5. "github.com/docker/docker/api/types"
  6. "github.com/docker/docker/api/types/filters"
  7. registrytypes "github.com/docker/docker/api/types/registry"
  8. "github.com/docker/docker/dockerversion"
  9. )
  10. var acceptedSearchFilterTags = map[string]bool{
  11. "is-automated": true,
  12. "is-official": true,
  13. "stars": true,
  14. }
  15. // SearchRegistryForImages queries the registry for images matching
  16. // term. authConfig is used to login.
  17. func (daemon *Daemon) SearchRegistryForImages(ctx context.Context, filtersArgs string, term string, limit int,
  18. authConfig *types.AuthConfig,
  19. headers map[string][]string) (*registrytypes.SearchResults, error) {
  20. searchFilters, err := filters.FromJSON(filtersArgs)
  21. if err != nil {
  22. return nil, err
  23. }
  24. if err := searchFilters.Validate(acceptedSearchFilterTags); err != nil {
  25. return nil, err
  26. }
  27. var isAutomated, isOfficial bool
  28. var hasStarFilter = 0
  29. if searchFilters.Contains("is-automated") {
  30. if searchFilters.UniqueExactMatch("is-automated", "true") {
  31. isAutomated = true
  32. } else if !searchFilters.UniqueExactMatch("is-automated", "false") {
  33. return nil, invalidFilter{"is-automated", searchFilters.Get("is-automated")}
  34. }
  35. }
  36. if searchFilters.Contains("is-official") {
  37. if searchFilters.UniqueExactMatch("is-official", "true") {
  38. isOfficial = true
  39. } else if !searchFilters.UniqueExactMatch("is-official", "false") {
  40. return nil, invalidFilter{"is-official", searchFilters.Get("is-official")}
  41. }
  42. }
  43. if searchFilters.Contains("stars") {
  44. hasStars := searchFilters.Get("stars")
  45. for _, hasStar := range hasStars {
  46. iHasStar, err := strconv.Atoi(hasStar)
  47. if err != nil {
  48. return nil, invalidFilter{"stars", hasStar}
  49. }
  50. if iHasStar > hasStarFilter {
  51. hasStarFilter = iHasStar
  52. }
  53. }
  54. }
  55. unfilteredResult, err := daemon.RegistryService.Search(ctx, term, limit, authConfig, dockerversion.DockerUserAgent(ctx), headers)
  56. if err != nil {
  57. return nil, err
  58. }
  59. filteredResults := []registrytypes.SearchResult{}
  60. for _, result := range unfilteredResult.Results {
  61. if searchFilters.Contains("is-automated") {
  62. if isAutomated != result.IsAutomated {
  63. continue
  64. }
  65. }
  66. if searchFilters.Contains("is-official") {
  67. if isOfficial != result.IsOfficial {
  68. continue
  69. }
  70. }
  71. if searchFilters.Contains("stars") {
  72. if result.StarCount < hasStarFilter {
  73. continue
  74. }
  75. }
  76. filteredResults = append(filteredResults, result)
  77. }
  78. return &registrytypes.SearchResults{
  79. Query: unfilteredResult.Query,
  80. NumResults: len(filteredResults),
  81. Results: filteredResults,
  82. }, nil
  83. }