katello 3.16.0.rc5.1 → 3.16.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of katello might be problematic. Click here for more details.

Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/katello/api/registry/registry_proxies_controller.rb +39 -23
  3. data/app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb +1 -1
  4. data/app/controllers/katello/api/v2/host_tracer_controller.rb +8 -33
  5. data/app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb +11 -1
  6. data/app/controllers/katello/api/v2/products_bulk_actions_controller.rb +15 -0
  7. data/app/controllers/katello/api/v2/repositories_controller.rb +10 -1
  8. data/app/controllers/katello/concerns/hosts_controller_extensions.rb +11 -5
  9. data/app/helpers/katello/content_view_helper.rb +15 -0
  10. data/app/lib/actions/katello/applicability/hosts/bulk_generate.rb +6 -2
  11. data/app/lib/actions/katello/capsule_content/refresh_repos.rb +1 -1
  12. data/app/lib/actions/katello/capsule_content/sync.rb +3 -2
  13. data/app/lib/actions/katello/capsule_content/sync_capsule.rb +17 -3
  14. data/app/lib/actions/katello/content_view/incremental_updates.rb +3 -1
  15. data/app/lib/actions/katello/content_view/publish.rb +55 -16
  16. data/app/lib/actions/katello/content_view_version/incremental_update.rb +84 -53
  17. data/app/lib/actions/katello/product/destroy.rb +25 -4
  18. data/app/lib/actions/katello/repository/destroy.rb +5 -1
  19. data/app/lib/actions/katello/repository/multi_clone_contents.rb +64 -0
  20. data/app/lib/actions/katello/repository/multi_clone_to_version.rb +30 -0
  21. data/app/lib/actions/katello/repository/sync.rb +35 -25
  22. data/app/lib/actions/katello/repository/update.rb +11 -16
  23. data/app/lib/actions/katello/repository/verify_checksum.rb +28 -0
  24. data/app/lib/actions/pulp/orchestration/repository/sync.rb +2 -1
  25. data/app/lib/actions/pulp/repository/sync.rb +2 -1
  26. data/app/lib/actions/pulp3/abstract_async_task.rb +63 -58
  27. data/app/lib/actions/pulp3/capsule_content/refresh_content_guard.rb +17 -0
  28. data/app/lib/actions/pulp3/capsule_content/sync.rb +3 -1
  29. data/app/lib/actions/pulp3/{ContentGuard → content_guard}/refresh.rb +0 -0
  30. data/app/lib/actions/pulp3/content_migration.rb +4 -0
  31. data/app/lib/actions/pulp3/content_view/delete_repository_references.rb +1 -1
  32. data/app/lib/actions/pulp3/orchestration/repository/copy_all_units.rb +2 -4
  33. data/app/lib/actions/pulp3/orchestration/repository/multi_copy_all_units.rb +36 -0
  34. data/app/lib/actions/pulp3/orchestration/repository/sync.rb +3 -1
  35. data/app/lib/actions/pulp3/orchestration/repository/trigger_update_repo_cert_guard.rb +22 -0
  36. data/app/lib/actions/pulp3/repository/copy_content.rb +0 -1
  37. data/app/lib/actions/pulp3/repository/delete.rb +1 -1
  38. data/app/lib/actions/pulp3/repository/multi_copy_content.rb +28 -0
  39. data/app/lib/actions/pulp3/repository/multi_copy_units.rb +14 -7
  40. data/app/lib/actions/pulp3/repository/presenters/repair_presenter.rb +85 -0
  41. data/app/lib/actions/pulp3/repository/repair.rb +29 -0
  42. data/app/lib/actions/pulp3/repository/save_version.rb +20 -8
  43. data/app/lib/actions/pulp3/repository/save_versions.rb +47 -13
  44. data/app/lib/actions/pulp3/repository/sync.rb +1 -1
  45. data/app/lib/actions/pulp3/repository/update_cv_repository_cert_guard.rb +6 -2
  46. data/app/lib/actions/pulp3/repository/upload_file.rb +1 -1
  47. data/app/lib/katello/concerns/base_template_scope_extensions.rb +4 -0
  48. data/app/lib/katello/errors.rb +1 -15
  49. data/app/lib/katello/resources/cdn.rb +3 -2
  50. data/app/lib/katello/util/cdn_var_substitutor.rb +9 -6
  51. data/app/models/katello/concerns/smart_proxy_extensions.rb +14 -3
  52. data/app/models/katello/content_view.rb +18 -6
  53. data/app/models/katello/content_view_erratum_filter.rb +13 -0
  54. data/app/models/katello/content_view_module_stream_filter.rb +19 -0
  55. data/app/models/katello/content_view_package_filter.rb +1 -1
  56. data/app/models/katello/glue/pulp/repo.rb +1 -1
  57. data/app/models/katello/host/content_facet.rb +1 -0
  58. data/app/models/katello/module_stream.rb +1 -1
  59. data/app/models/katello/ping.rb +1 -3
  60. data/app/models/katello/repository.rb +5 -0
  61. data/app/models/katello/root_repository.rb +5 -1
  62. data/app/models/setting/content.rb +1 -1
  63. data/app/services/cert/certs.rb +10 -2
  64. data/app/services/katello/host_trace_manager.rb +38 -0
  65. data/app/services/katello/pulp3/api/core.rb +4 -0
  66. data/app/services/katello/pulp3/erratum.rb +3 -1
  67. data/app/services/katello/pulp3/migration.rb +4 -3
  68. data/app/services/katello/pulp3/migration_plan.rb +6 -6
  69. data/app/services/katello/pulp3/repository.rb +16 -8
  70. data/app/services/katello/pulp3/repository/yum.rb +234 -35
  71. data/app/services/katello/pulp3/repository_mirror.rb +7 -2
  72. data/app/services/katello/pulp3/smart_proxy_mirror_repository.rb +1 -1
  73. data/app/services/katello/pulp3/task.rb +100 -0
  74. data/app/services/katello/pulp3/task_group.rb +85 -0
  75. data/app/services/katello/smart_proxy_helper.rb +13 -16
  76. data/config/routes/api/rhsm.rb +1 -0
  77. data/config/routes/api/v2.rb +2 -6
  78. data/config/routes/overrides.rb +4 -0
  79. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/content-hosts-bulk-traces-modal.controller.js +3 -4
  80. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/hosts/host-bulk-action.factory.js +2 -1
  81. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/bulk/product-bulk-action.factory.js +1 -0
  82. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details.controller.js +6 -0
  83. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-details.html +7 -1
  84. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html +1 -1
  85. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/views/new-repository.html +2 -2
  86. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/repository.factory.js +1 -0
  87. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/products.controller.js +15 -0
  88. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/views/products.html +6 -0
  89. data/lib/katello/permission_creator.rb +2 -2
  90. data/lib/katello/permissions/host_permissions.rb +1 -0
  91. data/lib/katello/plugin.rb +0 -1
  92. data/lib/katello/tasks/pulp3_post_migration_check.rake +2 -1
  93. data/lib/katello/tasks/reimport.rake +1 -1
  94. data/lib/katello/version.rb +1 -1
  95. data/webpack/redux/actions/RedHatRepositories/helpers.js +6 -6
  96. metadata +30 -13
  97. data/app/lib/actions/katello/repository/update_cv_repo_cert_guard.rb +0 -17
  98. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/hosts/host-traces-resolve.factory.js +0 -18
@@ -11,6 +11,11 @@ module Katello
11
11
  @repo_service = repository_service
12
12
  end
13
13
 
14
+ def content_guard_href
15
+ content_guard_api = ::Katello::Pulp3::Api::ContentGuard.new(smart_proxy)
16
+ content_guard_api.list&.results&.first&.pulp_href
17
+ end
18
+
14
19
  def backend_object_name
15
20
  #Create repos in pulp3 instance with the name as this repo's pulp_id
16
21
  repo.pulp_id
@@ -78,6 +83,7 @@ module Katello
78
83
  base_path: path,
79
84
  name: "#{backend_object_name}"
80
85
  }
86
+ ret[:content_guard] = repo.unprotected ? nil : content_guard_href
81
87
  ret[:publication] = options[:publication] if options.key? :publication
82
88
  ret[:repository_version] = options[:repository_version] if options.key? :repository_version
83
89
  ret
@@ -85,10 +91,9 @@ module Katello
85
91
 
86
92
  def remote_options
87
93
  base_options = common_remote_options
94
+ base_options.merge(url: remote_feed_url)
88
95
  if (type_specific_options = repo_service.try(:mirror_remote_options))
89
96
  base_options.merge(type_specific_options)
90
- else
91
- base_options.merge(url: remote_feed_url)
92
97
  end
93
98
  end
94
99
 
@@ -10,7 +10,7 @@ module Katello
10
10
  repo_map = {}
11
11
 
12
12
  smart_proxy_helper = ::Katello::SmartProxyHelper.new(smart_proxy)
13
- katello_pulp_ids = smart_proxy_helper.repos_available_to_capsule.map(&:pulp_id)
13
+ katello_pulp_ids = smart_proxy_helper.combined_repos_available_to_capsule.map(&:pulp_id)
14
14
  pulp3_enabled_repo_types.each do |repo_type|
15
15
  api = repo_type.pulp3_service_class.api(smart_proxy)
16
16
  repo_map[api] = api.list_all.reject { |capsule_repo| katello_pulp_ids.include? capsule_repo.name }
@@ -0,0 +1,100 @@
1
+ module Katello
2
+ module Pulp3
3
+ class Task
4
+ # A call report Looks like: {"task":"/pulp/api/v3/tasks/5/"}
5
+ # {
6
+ # "pulp_href":"/pulp/api/v3/tasks/4/",
7
+ # "pulp_created":"2019-02-21T19:50:40.476767Z",
8
+ # "job_id":"d0359658-d926-47a2-b430-1b2092b3bd86",
9
+ # "state":"completed",
10
+ # "name":"pulp_file.app.tasks.publishing.publish",
11
+ # "started_at":"2019-02-21T19:50:40.556002Z",
12
+ # "finished_at":"2019-02-21T19:50:40.618397Z",
13
+ # "non_fatal_errors":[
14
+ #
15
+ # ],
16
+ # "error":null,
17
+ # "worker":"/pulp/api/v3/workers/1/",
18
+ # "parent":null,
19
+ # "spawned_tasks":[
20
+ #
21
+ # ],
22
+ # "progress_reports":[
23
+ #
24
+ # ],
25
+ # "created_resources":[
26
+ # "/pulp/api/v3/publications/1/"
27
+ # ]
28
+ # }
29
+
30
+ WAITING = 'waiting'.freeze
31
+ SKIPPED = 'skipped'.freeze
32
+ RUNNING = 'running'.freeze
33
+ COMPLETED = 'completed'.freeze
34
+ FAILED = 'failed'.freeze
35
+ CANCELED = 'canceled'.freeze
36
+
37
+ FINISHED_STATES = [COMPLETED, FAILED, CANCELED, SKIPPED].freeze
38
+
39
+ #needed for serialization in dynflow
40
+
41
+ delegate :[], :key?, :dig, :to_hash, :to => :task_data
42
+
43
+ def initialize(smart_proxy, data)
44
+ @smart_proxy = smart_proxy
45
+ if (href = data['task'])
46
+ @href = href
47
+ else
48
+ @pulp_data = data.with_indifferent_access
49
+ @href = @pulp_data['pulp_href']
50
+ Rails.logger.error("Got empty pulp_href on #{@pulp_data}") if @href.nil?
51
+ end
52
+ end
53
+
54
+ def task_data(force_refresh = false)
55
+ @pulp_data = nil if force_refresh
56
+ @pulp_data ||= tasks_api.read(@href).as_json.with_indifferent_access
57
+ end
58
+
59
+ def tasks_api
60
+ ::Katello::Pulp3::Api::Core.new(@smart_proxy).tasks_api
61
+ end
62
+
63
+ def task_group_href
64
+ task_data[:task_group]
65
+ end
66
+
67
+ def done?
68
+ task_data[:finish_time] || FINISHED_STATES.include?(task_data[:state])
69
+ end
70
+
71
+ def poll
72
+ task_data(true)
73
+ self
74
+ end
75
+
76
+ def started?
77
+ task_data[:start_time]
78
+ end
79
+
80
+ def error
81
+ if task_data[:state] == CANCELED
82
+ _("Task canceled")
83
+ elsif task_data[:state] == FAILED
84
+ if task_data[:error][:description].blank?
85
+ _("Pulp task error")
86
+ else
87
+ task_data[:error][:description]
88
+ end
89
+ end
90
+ end
91
+
92
+ def cancel
93
+ data = PulpcoreClient::TaskResponse.new(state: 'canceled')
94
+ tasks_api.tasks_cancel(task_data['pulp_href'], data)
95
+ #the main task may have completed, so cancel spawned tasks too
96
+ task_data['spawned_tasks']&.each { |spawned| tasks_api.tasks_cancel(spawned['pulp_href'], data) }
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,85 @@
1
+ module Katello
2
+ module Pulp3
3
+ class TaskGroup
4
+ WAITING = 'waiting'.freeze
5
+ SKIPPED = 'skipped'.freeze
6
+ RUNNING = 'running'.freeze
7
+ COMPLETED = 'completed'.freeze
8
+ CANCELLED = 'canceled'.freeze
9
+ FAILED = 'failed'.freeze
10
+
11
+ IN_PROGRESS_STATES = [WAITING, RUNNING].freeze
12
+
13
+ #needed for serialization in dynflow
14
+ delegate :to_hash, :to => :task_group_data
15
+ delegate :dig, :to => :task_group_data
16
+
17
+ attr_accessor :href
18
+
19
+ # A call report Looks like: {"task":"/pulp/api/v3/tasks/5/"}
20
+ #{
21
+ # "pulp_href":"/pulp/api/v3/task-groups/d9841aaa-8a47-4e31-9018-10e4430766bf/",
22
+ # "description":"Migration Sub-tasks",
23
+ # "waiting":0,
24
+ # "skipped":0,
25
+ # "running":0,
26
+ # "completed":0,
27
+ # "canceled":0,
28
+ # "failed":1
29
+ # }
30
+
31
+ def self.new_from_href(smart_proxy, href)
32
+ group = self.new(smart_proxy, {'pulp_href' => href})
33
+ group.clear_task_group_data
34
+ group
35
+ end
36
+
37
+ def initialize(smart_proxy, data)
38
+ @smart_proxy = smart_proxy
39
+ @pulp_data = data.with_indifferent_access
40
+ @href = @pulp_data['pulp_href']
41
+ Rails.logger.error("Got empty pulp_href on #{@pulp_data}") if @href.nil?
42
+ end
43
+
44
+ def task_group_data
45
+ @pulp_data ||= tasks_groups_api.read(@href).as_json.with_indifferent_access
46
+ end
47
+
48
+ def tasks_groups_api
49
+ ::Katello::Pulp3::Api::Core.new(@smart_proxy).task_groups_api
50
+ end
51
+
52
+ def done?
53
+ task_group_data['all_tasks_dispatched'] = true && IN_PROGRESS_STATES.all? { |state| task_group_data[state] == 0 }
54
+ end
55
+
56
+ def poll
57
+ clear_task_group_data
58
+ task_group_data
59
+ end
60
+
61
+ def clear_task_group_data
62
+ @pulp_data = nil
63
+ end
64
+
65
+ def started?
66
+ [SKIPPED, RUNNING, COMPLETED, CANCELLED, FAILED].any? { |state| task_group_data[state] }
67
+ end
68
+
69
+ def error
70
+ if task_group_data[FAILED] > 0
71
+ "#{task_group_data[FAILED]} subtask(s) failed for task group #{@href}."
72
+ end
73
+ end
74
+
75
+ def cancel
76
+ tasks_api = ::Katello::Pulp3::Api::Core.new(@smart_proxy).tasks_api
77
+ tasks_response = tasks_api.list(task_group: task_group_data['pulp_href'])
78
+ data = PulpcoreClient::TaskResponse.new(state: 'canceled')
79
+ tasks_response.results.collect do |result|
80
+ tasks_api.tasks_cancel(result.pulp_href, data)
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -13,34 +13,31 @@ module Katello
13
13
  @smart_proxy.pulp_master?
14
14
  end
15
15
 
16
- def repos_available_to_capsule(environment = nil, content_view = nil, repository = nil)
17
- ret = []
18
- if repository
19
- environment = repository.environment
20
- ret = [repository]
21
- else
22
- yum_repos = fetch_repos_available_to_capsule(environment, content_view) || []
23
- puppet_envs = fetch_puppet_environments_available_to_capsule(environment, content_view) || []
24
- ret = yum_repos + puppet_envs
25
- end
16
+ def lifecycle_environment_check(environment = nil, repository = nil)
17
+ environment = repository.environment if repository
26
18
 
27
19
  if environment && !self.smart_proxy.lifecycle_environments.include?(environment)
28
20
  fail _("Lifecycle environment '%{environment}' is not attached to this capsule.") % { :environment => environment.name }
29
21
  end
30
-
31
- ret
32
22
  end
33
23
 
34
- private
24
+ def combined_repos_available_to_capsule(environment = nil, content_view = nil, repository = nil)
25
+ lifecycle_environment_check(environment, repository)
26
+ if repository
27
+ [repository]
28
+ else
29
+ repositories_available_to_capsule(environment, content_view) + puppet_environments_available_to_capsule(environment, content_view)
30
+ end
31
+ end
35
32
 
36
- def fetch_repos_available_to_capsule(environments = nil, content_view = nil)
33
+ def repositories_available_to_capsule(environments, content_view)
37
34
  environments = @smart_proxy.lifecycle_environments if environments.nil?
38
35
  yum_repos = Katello::Repository.in_environment(environments)
39
36
  yum_repos = yum_repos.in_content_views([content_view]) if content_view
40
- yum_repos.select(&:node_syncable?)
37
+ yum_repos.smart_proxy_syncable
41
38
  end
42
39
 
43
- def fetch_puppet_environments_available_to_capsule(environments = nil, content_view = nil)
40
+ def puppet_environments_available_to_capsule(environments, content_view)
44
41
  environments = @smart_proxy.lifecycle_environments if environments.nil?
45
42
  puppet_environments = Katello::ContentViewPuppetEnvironment.in_environment(environments)
46
43
  puppet_environments = puppet_environments.in_content_view(content_view) if content_view
@@ -21,6 +21,7 @@ Katello::Engine.routes.draw do
21
21
  match '/owners/:organization_id/environments' => 'candlepin_proxies#rhsm_index', :via => :get
22
22
  match '/owners/:organization_id/pools' => 'candlepin_proxies#get', :via => :get, :as => :proxy_owner_pools_path
23
23
  match '/owners/:organization_id/servicelevels' => 'candlepin_proxies#get', :via => :get, :as => :proxy_owner_servicelevels_path
24
+ match '/owners/:organization_id/system_purpose' => 'candlepin_proxies#get', :via => :get, :as => :proxy_owner_system_purpose_path
24
25
  match '/environments/:environment_id/consumers' => 'candlepin_proxies#consumer_create', :via => :post
25
26
  match '/consumers/:id' => 'candlepin_proxies#consumer_show', :via => :get
26
27
  match '/consumers/:id' => 'candlepin_proxies#regenerate_identity_certificates', :via => :post
@@ -304,12 +304,6 @@ Katello::Engine.routes.draw do
304
304
  end
305
305
  end
306
306
 
307
- api_resources :traces, :only => [], :controller => 'host_tracer' do
308
- collection do
309
- put :resolve
310
- end
311
- end
312
-
313
307
  api_resources :srpms, :only => [:index, :show], :controller => 'srpms' do
314
308
  collection do
315
309
  get :auto_complete_search
@@ -392,6 +386,7 @@ Katello::Engine.routes.draw do
392
386
  put :remove_docker_manifests, :action => :remove_content
393
387
  put :remove_content
394
388
  post :sync
389
+ post :verify_checksum
395
390
  post :export
396
391
  post :upload_content
397
392
  put :import_uploads
@@ -421,6 +416,7 @@ Katello::Engine.routes.draw do
421
416
  collection do
422
417
  match '/bulk/destroy' => 'products_bulk_actions#destroy_products', :via => :put
423
418
  match '/bulk/sync' => 'products_bulk_actions#sync_products', :via => :put
419
+ match '/bulk/verify_checksum' => 'products_bulk_actions#verify_checksum_products', :via => :put
424
420
  match '/bulk/sync_plan' => 'products_bulk_actions#update_sync_plans', :via => :put
425
421
  match '/bulk/http_proxy' => 'products_bulk_actions#update_http_proxy', :via => :put
426
422
  end
@@ -77,6 +77,7 @@ Foreman::Application.routes.draw do
77
77
  match '/bulk/environment_content_view' => 'hosts_bulk_actions#environment_content_view', :via => :put
78
78
  match '/bulk/release_version' => 'hosts_bulk_actions#release_version', :via => :put
79
79
  match '/bulk/traces' => 'hosts_bulk_actions#traces', :via => :post
80
+ match '/bulk/resolve_traces' => 'hosts_bulk_actions#resolve_traces', :via => :put
80
81
  match '/bulk/available_incremental_updates' => 'hosts_bulk_actions#available_incremental_updates', :via => :post
81
82
  match '/bulk/module_streams' => 'hosts_bulk_actions#module_streams', :via => :post
82
83
  match '/subscriptions/' => 'host_subscriptions#create', :via => :post
@@ -114,6 +115,9 @@ Foreman::Application.routes.draw do
114
115
  end
115
116
 
116
117
  resources :traces, :only => [:index], :controller => :host_tracer do
118
+ collection do
119
+ put :resolve
120
+ end
117
121
  end
118
122
  end
119
123
  end
@@ -9,7 +9,6 @@
9
9
  * @requires Nutupane
10
10
  * @requires BastionConfig
11
11
  * @requires hostIds
12
- * @requires HostTracesResolve
13
12
  * @required ContentHostsHelper
14
13
  * @requires translate
15
14
  *
@@ -18,8 +17,8 @@
18
17
  */
19
18
  /*jshint camelcase:false*/
20
19
  angular.module('Bastion.content-hosts').controller('ContentHostsBulkTracesController',
21
- ['$scope', '$uibModalInstance', 'HostBulkAction', 'Notification', 'Nutupane', 'BastionConfig', 'hostIds', 'HostTracesResolve', 'ContentHostsHelper', 'translate',
22
- function ($scope, $uibModalInstance, HostBulkAction, Notification, Nutupane, BastionConfig, hostIds, HostTracesResolve, ContentHostsHelper, translate) {
20
+ ['$scope', '$uibModalInstance', 'HostBulkAction', 'Notification', 'Nutupane', 'BastionConfig', 'hostIds', 'ContentHostsHelper', 'translate',
21
+ function ($scope, $uibModalInstance, HostBulkAction, Notification, Nutupane, BastionConfig, hostIds, ContentHostsHelper, translate) {
23
22
 
24
23
  var tracesNutupane = new Nutupane(HostBulkAction, hostIds, 'traces');
25
24
  tracesNutupane.enableSelectAllResults();
@@ -46,7 +45,7 @@ angular.module('Bastion.content-hosts').controller('ContentHostsBulkTracesContro
46
45
  });
47
46
  };
48
47
  /* eslint-disable camelcase */
49
- HostTracesResolve.resolve({trace_ids: traceids}, onSuccess, onFailure);
48
+ HostBulkAction.resolveTraces({trace_ids: traceids}, onSuccess, onFailure);
50
49
  /* eslint-enable camelcase */
51
50
  };
52
51
 
@@ -26,7 +26,8 @@ angular.module('Bastion.hosts').factory('HostBulkAction',
26
26
  releaseVersion: {method: 'PUT', params: {action: 'release_version'}},
27
27
  availableIncrementalUpdates: {method: 'POST', isArray: true, params: {action: 'available_incremental_updates'}},
28
28
  moduleStreams: {method: 'POST', params: {action: 'module_streams'}},
29
- traces: {method: 'POST', params: {action: 'traces'}}
29
+ traces: {method: 'POST', params: {action: 'traces'}},
30
+ resolveTraces: {method: 'PUT', isArray: true, params: {action: 'resolve_traces'}}
30
31
  });
31
32
 
32
33
  }]
@@ -13,6 +13,7 @@ angular.module('Bastion.products').factory('ProductBulkAction',
13
13
  return BastionResource('katello/api/v2/products/bulk/:action', {}, {
14
14
  removeProducts: {method: 'PUT', params: {action: 'destroy'}},
15
15
  syncProducts: {method: 'PUT', params: {action: 'sync'}},
16
+ verifyChecksumProducts: {method: 'PUT', params: {action: 'verify_checksum'}},
16
17
  updateProductSyncPlan: {method: 'PUT', params: {action: 'sync_plan'}},
17
18
  updateProductHttpProxy: {method: 'PUT', params: {action: 'http_proxy'}}
18
19
  });
@@ -70,6 +70,12 @@
70
70
  }, errorHandler);
71
71
  };
72
72
 
73
+ $scope.verifyChecksum = function (repository) {
74
+ Repository.verifyChecksum({id: repository.id}, function (task) {
75
+ $state.go('product.repository.tasks.details', {taskId: task.id});
76
+ }, errorHandler);
77
+ };
78
+
73
79
  $scope.republishRepository = function (repository) {
74
80
  Repository.republish({id: repository.id}, function (task) {
75
81
  $state.go('product.repository.tasks.details', {taskId: task.id});
@@ -32,6 +32,12 @@
32
32
  </a>
33
33
  </li>
34
34
 
35
+ <li role="menuitem" ng-hide="hideSyncButton(repository, true)" ng-class="{disabled: disableSyncLink()}">
36
+ <a ng-click="verifyChecksum(repository)" disable-link="disableSyncLink()" translate>
37
+ Verify Content Checksum
38
+ </a>
39
+ </li>
40
+
35
41
  <li role="menuitem" ng-hide="syncInProgress(repository.last_sync) || denied('edit_products', product)">
36
42
  <a ng-click="republishRepository(repository)" translate>
37
43
  Republish Repository Metadata
@@ -90,4 +96,4 @@
90
96
  <div data-block="content">
91
97
  <section ui-view></section>
92
98
  </div>
93
- </div>
99
+ </div>
@@ -208,7 +208,7 @@
208
208
  <dt translate>Publish via HTTPS</dt>
209
209
  <dd translate>Yes</dd>
210
210
 
211
- <span ng-hide="repository.content_type === 'ostree'">
211
+ <span ng-hide="repository.content_type === 'ostree' || repository.content_type === 'docker'">
212
212
  <dt translate>Publish via HTTP</dt>
213
213
  <dd bst-edit-checkbox="repository.unprotected"
214
214
  formatter="booleanToYesNo"
@@ -63,7 +63,7 @@
63
63
  ng-model="repository.url"
64
64
  type="text"/>
65
65
  <p class="help-block" ng-show="repository.content_type === 'docker'" translate>
66
- URL of the registry you want to sync. Example: https://registry-1.docker.io/
66
+ URL of the registry you want to sync. Example: https://registry-1.docker.io/ or https://quay.io/
67
67
  </p>
68
68
  <p class="help-block" ng-show="repository.content_type === 'ansible_collection'" translate>
69
69
  Content synced depends on the specifity of the URL and/or the optional requirements.yaml specified below <a class="fa fa-question-circle" ng-show="repository.content_type === 'ansible_collection'"
@@ -144,7 +144,7 @@
144
144
  ng-model="repository.docker_upstream_name"
145
145
  type="text"/>
146
146
  <p class="help-block" translate>
147
- Name of the upstream repository you want to sync. Example: 'busybox' or 'fedora/ssh'.
147
+ Name of the upstream repository you want to sync. Example: 'quay/busybox' or 'fedora/ssh'.
148
148
  </p>
149
149
 
150
150
  </div>
@@ -17,6 +17,7 @@ angular.module('Bastion.repositories').factory('Repository',
17
17
  {
18
18
  update: { method: 'PUT' },
19
19
  sync: { method: 'POST', params: { action: 'sync' } },
20
+ verifyChecksum: { method: 'POST', params: { action: 'verify_checksum' }},
20
21
  removePackages: { method: 'PUT', params: { action: 'remove_packages'}},
21
22
  removeContent: { method: 'PUT', params: { action: 'remove_content'}},
22
23
  autocomplete: {method: 'GET', isArray: true, params: {id: 'auto_complete_search'}},