search.go 2.6 KB

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