From 57de968a92f84a15736bbe37a5804fee7c47778c Mon Sep 17 00:00:00 2001 From: Pawel Chojnacki Date: Fri, 23 Feb 2018 21:33:33 +0100 Subject: Squashed commit of the following: commit 22e1cb8f4b98f71d21026f69aa3e68d79946d6ae Merge: 766a42a9639 e966c6aea25 Author: Pawel Chojnacki Date: Fri Feb 23 21:30:46 2018 +0100 Merge remote-tracking branch 'upstream/master' into 38783-add-cluster-metrics.yml # Conflicts: # app/controllers/projects/prometheus/metrics_controller.rb # app/controllers/projects/prometheus_controller.rb # app/models/project_services/prometheus_service.rb # lib/gitlab/prometheus/queries/query_additional_metrics.rb # spec/controllers/projects/prometheus/metrics_controller_spec.rb # spec/models/project_services/prometheus_service_spec.rb commit 766a42a96393f502d439c1f0beb0b6cfb2c228d4 Author: Pawel Chojnacki Date: Fri Feb 23 17:58:45 2018 +0100 Move prometheus adapter to app/models/concerns commit ca84eed49811cf3064a2e5ea611af1c947c590d7 Merge: 66702099586 cb504cedc2a Author: Pawel Chojnacki Date: Fri Feb 23 15:36:03 2018 +0100 Merge remote-tracking branch 'upstream/backport_custom_metrics_ce_components' into 38783-add-cluster-metrics.yml + fix failing tests # Conflicts: # app/controllers/projects/prometheus_controller.rb # app/models/project_services/prometheus_service.rb # lib/gitlab/prometheus/queries/query_additional_metrics.rb # spec/models/project_services/prometheus_service_spec.rb commit cb504cedc2a6e353ffb56833334681e3da09fc14 Author: Pawel Chojnacki Date: Fri Feb 23 14:46:15 2018 +0100 Fix prometheus_service found by find_or_initialize_service commit 928b84c72c2c4c46e1785b9a943c1822a137de16 Author: Pawel Chojnacki Date: Thu Feb 22 23:15:11 2018 +0100 additional metrics and backported tests commit 41291383b4b6976af94eaf9e1a7b2e2a172310e7 Author: Pawel Chojnacki Date: Thu Feb 22 21:57:45 2018 +0100 Introduce Metrics controller and retire prometheus controller commit 6e7492e4c7ffa9d8621f09198071bc14be875976 Author: Pawel Chojnacki Date: Thu Feb 22 21:46:37 2018 +0100 Backport PrometheusClient::Error and all->common_metrics rename commit 66702099586c864a7f78970a0ee0dd9f3c2beeef Author: Pawel Chojnacki Date: Thu Feb 22 20:23:03 2018 +0100 fix failing tests commit ce921ea723cde61b2441ba98c9aca97606c719c8 Author: Mike Greiling Date: Wed Feb 21 23:47:30 2018 -0600 add labels to cluster metrics commit 993830c6892e4fbf53d3f72da00002d642c7e9b2 Author: Pawel Chojnacki Date: Thu Feb 22 01:20:49 2018 +0100 Fix formatting probelms and few small tests commit 66ee65d8e3f747c90d986bc3056178422156bc8e Author: Pawel Chojnacki Date: Thu Feb 22 01:08:03 2018 +0100 stop using in deployment tests environment.id commit 62c91978d15f0369988521363dae24bd7510d68d Author: Pawel Chojnacki Date: Thu Feb 22 01:06:33 2018 +0100 fix prometheus_controller and adapter tests commit 977b1d34c1d03c7233582e8328f85caf634895ed Author: Pawel Chojnacki Date: Thu Feb 22 00:19:39 2018 +0100 finish up active? -> can_query? rename commit e614f7daee58a9758d83ba3efe1649c8b80bc1e2 Author: Pawel Chojnacki Date: Wed Feb 21 23:51:33 2018 +0100 deployment prometheus adapter tests fix commit ebd726c114a6026fef0adf3eba6ee1972530148a Author: Pawel Chojnacki Date: Wed Feb 21 21:40:40 2018 +0100 Move environment dependant tests to environment commit 6d31311cd3729c29233283dded70e03a4a9a3c97 Author: Pawel Chojnacki Date: Wed Feb 21 20:40:24 2018 +0100 update monitoring service and move adding dpeloyment_time to deployment model commit 60b6bf391ab36846dce122bc6b0c5196a186267c Author: Pawel Chojnacki Date: Wed Feb 21 20:15:46 2018 +0100 adjust deployment spec and prometheus specs commit 6681662cf1c028aff2ff94aa0501732cb7119ba1 Author: Pawel Chojnacki Date: Tue Feb 20 22:30:20 2018 +0100 Revert changes to reactive caching commit e282f86c45a056889f57d3f7fd23a81c88efff6a Merge: 5751c73df59 6844a2df873 Author: Pawel Chojnacki Date: Tue Feb 20 22:08:17 2018 +0100 Merge remote-tracking branch 'upstream/master' into 38783-add-cluster-metrics.yml commit 5751c73df59d0a03840a1b4b71b0637670f971a6 Author: Pawel Chojnacki Date: Tue Feb 20 22:07:43 2018 +0100 rename active? to can_query? and cleanup environment prometheus router commit 3f3c6e1d33dcd9315979daf26a95f2aab83a7de9 Author: Pawel Chojnacki Date: Tue Feb 20 21:51:43 2018 +0100 Fix tests, and only use prometheus service if its active commit 6345838bac584c213b665d334252ccab202cb271 Author: Pawel Chojnacki Date: Tue Feb 20 16:24:27 2018 +0100 Fix typo commit 7a585d32afe8da050b5615b1d036a550e06479f5 Author: Pawel Chojnacki Date: Tue Feb 20 15:29:40 2018 +0100 Cluster id is not required commit e6af62afb11fa380f6aff1c31a81bcc9bab3b1eb Author: Pawel Chojnacki Date: Tue Feb 20 15:15:46 2018 +0100 Result transformation support commit f3b1bd7c67894f44efe33591ddb70093bd620c03 Author: Pawel Chojnacki Date: Tue Feb 20 15:07:07 2018 +0100 Fix rubocop warning and exten cluster query timeframe commit be77947cea64261a4d3dead33c3c57f413a9880c Author: Pawel Chojnacki Date: Tue Feb 20 14:42:47 2018 +0100 Fix additional metrics test commit eb3922e16221abe16f59fae1c38122f227643343 Author: Pawel Chojnacki Date: Tue Feb 20 14:34:44 2018 +0100 rename prometheus adapter methods commit 045476cd08b21593818b274ae8a44d19b705523f Author: Pawel Chojnacki Date: Tue Feb 20 13:19:36 2018 +0100 Make prometheus adapter a module commit f2daf050d8c689f72c4c61207930bc53c331f12e Author: Pawel Chojnacki Date: Tue Feb 20 12:00:44 2018 +0100 refactoring wip commit 52e4ef5587794e811dc10a0f2dca522342a865da Author: Pawel Chojnacki Date: Sun Feb 18 20:25:55 2018 +0100 cleanup prometheus adapter concept commit 3887365faab9dfcd9c00bcfc501d09ac62431a03 Author: Pawel Chojnacki Date: Sun Feb 18 19:22:11 2018 +0100 Refactor out deployment id, Rename PrometheusQuerier to PrometheusAdapter commit aa2fc2df57bd72c9a5e94f66d1f1e23990be6c3f Author: Pawel Chojnacki Date: Fri Feb 16 23:59:54 2018 +0100 Refactor prometheus client commit e43c1ca9d9874d6cf1569f40fa1aca158d9d5d91 Author: Pawel Chojnacki Date: Thu Feb 15 20:24:45 2018 +0100 Use initial version of cluster_metrics.yml commit 867821ce0b2609ebf8994220aa8e3a94d66a01e0 Author: Pawel Chojnacki Date: Thu Feb 15 05:24:14 2018 +0100 Fix querying cluster metrics commit 1601e002a064cbb10ffe110a19433c5662858f1d Author: Pawel Chojnacki Date: Thu Feb 15 04:49:03 2018 +0100 Queues for unicersal querier commit 5db198fdc925c0223be24939b76da1d544dd569c Author: Pawel Chojnacki Date: Thu Feb 15 03:35:17 2018 +0100 refactor reactive caching and prometheus querying commit b0fc00e8c9d21e961ef44b0129103e2a62928b52 Author: Pawel Chojnacki Date: Thu Feb 15 00:12:03 2018 +0100 Add generic query additional metrics commit ffe76e6a9ba196bccff22c4880e0384959ad5e48 Author: Pawel Chojnacki Date: Tue Feb 13 15:40:15 2018 +0100 Cluster Metric yml initial + Remove cluster query + remove cluster_metrics.yml + Prometheus adapter tests --- .../monitoring/utils/multiple_time_series.js | 2 +- app/controllers/projects/deployments_controller.rb | 2 +- .../projects/prometheus/metrics_controller.rb | 11 ++- app/models/clusters/applications/prometheus.rb | 4 +- app/models/clusters/cluster.rb | 1 - app/models/clusters/platforms/kubernetes.rb | 2 +- app/models/concerns/prometheus_adapter.rb | 48 ++++++++++++ app/models/deployment.rb | 17 +++-- app/models/environment.rb | 33 ++++++--- app/models/project_services/monitoring_service.rb | 4 +- app/models/project_services/prometheus_service.rb | 85 +--------------------- 11 files changed, 101 insertions(+), 108 deletions(-) create mode 100644 app/models/concerns/prometheus_adapter.rb (limited to 'app') diff --git a/app/assets/javascripts/monitoring/utils/multiple_time_series.js b/app/assets/javascripts/monitoring/utils/multiple_time_series.js index 4ce3dad440c..b5b8e3c255d 100644 --- a/app/assets/javascripts/monitoring/utils/multiple_time_series.js +++ b/app/assets/javascripts/monitoring/utils/multiple_time_series.js @@ -76,7 +76,7 @@ function queryTimeSeries(query, graphWidth, graphHeight, graphHeightOffset, xDom metricTag = seriesCustomizationData.value || timeSeriesMetricLabel; [lineColor, areaColor] = pickColor(seriesCustomizationData.color); } else { - metricTag = timeSeriesMetricLabel || `series ${timeSeriesNumber + 1}`; + metricTag = timeSeriesMetricLabel || query.label || `series ${timeSeriesNumber + 1}`; [lineColor, areaColor] = pickColor(); } diff --git a/app/controllers/projects/deployments_controller.rb b/app/controllers/projects/deployments_controller.rb index 1a418d0f15a..b68cdc39cb8 100644 --- a/app/controllers/projects/deployments_controller.rb +++ b/app/controllers/projects/deployments_controller.rb @@ -24,7 +24,7 @@ class Projects::DeploymentsController < Projects::ApplicationController end def additional_metrics - return render_404 unless deployment.has_additional_metrics? + return render_404 unless deployment.has_metrics? respond_to do |format| format.json do diff --git a/app/controllers/projects/prometheus/metrics_controller.rb b/app/controllers/projects/prometheus/metrics_controller.rb index b739d0f0f90..255fbf254fb 100644 --- a/app/controllers/projects/prometheus/metrics_controller.rb +++ b/app/controllers/projects/prometheus/metrics_controller.rb @@ -2,11 +2,12 @@ module Projects module Prometheus class MetricsController < Projects::ApplicationController before_action :authorize_admin_project! + before_action :require_prometheus_metrics! def active_common respond_to do |format| format.json do - matched_metrics = prometheus_service.matched_metrics || {} + matched_metrics = prometheus_adapter.query(:matched_metrics) || {} if matched_metrics.any? render json: matched_metrics @@ -19,8 +20,12 @@ module Projects private - def prometheus_service - @prometheus_service ||= project.find_or_initialize_service('prometheus') + def prometheus_adapter + project.prometheus_service + end + + def require_prometheus_metrics! + render_404 unless prometheus_adapter.can_query? end end end diff --git a/app/models/clusters/applications/prometheus.rb b/app/models/clusters/applications/prometheus.rb index aa22e9d5d58..ba63d0f3c64 100644 --- a/app/models/clusters/applications/prometheus.rb +++ b/app/models/clusters/applications/prometheus.rb @@ -1,6 +1,8 @@ module Clusters module Applications class Prometheus < ActiveRecord::Base + include PrometheusAdapter + VERSION = "2.0.0".freeze self.table_name = 'clusters_applications_prometheus' @@ -38,7 +40,7 @@ module Clusters Gitlab::Kubernetes::Helm::InstallCommand.new(name, chart: chart, chart_values_file: chart_values_file) end - def proxy_client + def prometheus_client return unless kube_client proxy_url = kube_client.proxy_url('service', service_name, service_port, Gitlab::Kubernetes::Helm::NAMESPACE) diff --git a/app/models/clusters/cluster.rb b/app/models/clusters/cluster.rb index 8678f70f78c..1fd7db30107 100644 --- a/app/models/clusters/cluster.rb +++ b/app/models/clusters/cluster.rb @@ -50,7 +50,6 @@ module Clusters scope :disabled, -> { where(enabled: false) } scope :for_environment, -> (env) { where(environment_scope: ['*', '', env.slug]) } - scope :for_all_environments, -> { where(environment_scope: ['*', '']) } def status_name if provider diff --git a/app/models/clusters/platforms/kubernetes.rb b/app/models/clusters/platforms/kubernetes.rb index 7ce8befeeeb..66f629df1b4 100644 --- a/app/models/clusters/platforms/kubernetes.rb +++ b/app/models/clusters/platforms/kubernetes.rb @@ -141,7 +141,7 @@ module Clusters end def kubeclient_ssl_options - opts = { verify_ssl: OpenSSL::SSL::VERIFY_PEER } + opts = { verify_ssl: OpenSSL::SSL::VERIFY_NONE } if ca_pem.present? opts[:cert_store] = OpenSSL::X509::Store.new diff --git a/app/models/concerns/prometheus_adapter.rb b/app/models/concerns/prometheus_adapter.rb new file mode 100644 index 00000000000..fea99a7cd35 --- /dev/null +++ b/app/models/concerns/prometheus_adapter.rb @@ -0,0 +1,48 @@ +module PrometheusAdapter + extend ActiveSupport::Concern + + included do + include ReactiveCaching + + self.reactive_cache_key = ->(adapter) { [adapter.class.model_name.singular, adapter.id] } + self.reactive_cache_lease_timeout = 30.seconds + self.reactive_cache_refresh_interval = 30.seconds + self.reactive_cache_lifetime = 1.minute + + def prometheus_client + raise NotImplementedError + end + + def prometheus_client_wrapper + Gitlab::PrometheusClient.new(prometheus_client) + end + + def can_query? + prometheus_client.present? + end + + def query(query_name, *args) + return unless can_query? + + query_class = Gitlab::Prometheus::Queries.const_get("#{query_name.to_s.classify}Query") + + args.map! { |arg| arg.id } + + with_reactive_cache(query_class.name, *args, &query_class.method(:transform_reactive_result)) + end + + # Cache metrics for specific environment + def calculate_reactive_cache(query_class_name, *args) + return unless prometheus_client + + data = Kernel.const_get(query_class_name).new(prometheus_client_wrapper).query(*args) + { + success: true, + data: data, + last_update: Time.now.utc + } + rescue Gitlab::PrometheusClient::Error => err + { success: false, result: err.message } + end + end +end diff --git a/app/models/deployment.rb b/app/models/deployment.rb index b6cf168d60e..66e61c06765 100644 --- a/app/models/deployment.rb +++ b/app/models/deployment.rb @@ -98,28 +98,29 @@ class Deployment < ActiveRecord::Base end def has_metrics? - project.monitoring_service.present? + prometheus_adapter&.can_query? end def metrics return {} unless has_metrics? - project.monitoring_service.deployment_metrics(self) - end - - def has_additional_metrics? - project.prometheus_service.present? + metrics = prometheus_adapter.query(:deployment, self) + metrics&.merge(deployment_time: created_at.to_i) || {} end def additional_metrics - return {} unless project.prometheus_service.present? + return {} unless has_metrics? - metrics = project.prometheus_service.additional_deployment_metrics(self) + metrics = prometheus_adapter.query(:additional_metrics_deployment, self) metrics&.merge(deployment_time: created_at.to_i) || {} end private + def prometheus_adapter + environment.prometheus_adapter + end + def ref_path File.join(environment.ref_path, 'deployments', iid.to_s) end diff --git a/app/models/environment.rb b/app/models/environment.rb index f78c21aebe5..2a91bd07b28 100644 --- a/app/models/environment.rb +++ b/app/models/environment.rb @@ -146,21 +146,15 @@ class Environment < ActiveRecord::Base end def has_metrics? - project.monitoring_service.present? && available? && last_deployment.present? + prometheus_adapter&.can_query? && available? && last_deployment.present? end def metrics - project.monitoring_service.environment_metrics(self) if has_metrics? - end - - def has_additional_metrics? - project.prometheus_service.present? && available? && last_deployment.present? + prometheus_adapter.query(:environment, self) if has_metrics? end def additional_metrics - if has_additional_metrics? - project.prometheus_service.additional_environment_metrics(self) - end + prometheus_adapter.query(:additional_metrics_environment, self) if has_metrics? end def slug @@ -226,6 +220,27 @@ class Environment < ActiveRecord::Base self.environment_type || self.name end + def prometheus_adapter + @prometheus_adapter ||= if service_prometheus_adapter.can_query? + service_prometheus_adapter + else + cluster_prometheus_adapter + end + end + + def service_prometheus_adapter + project.find_or_initialize_service('prometheus') + end + + def cluster_prometheus_adapter + # sort results by descending order based on environment_scope being longer + # thus more closely matching environment slug + clusters = project.clusters.enabled.for_environment(self).sort_by { |c| c.environment_scope&.length }.reverse! + + cluster = clusters&.detect { |cluster| cluster.application_prometheus&.installed? } + cluster&.application_prometheus + end + private # Slugifying a name may remove the uniqueness guarantee afforded by it being diff --git a/app/models/project_services/monitoring_service.rb b/app/models/project_services/monitoring_service.rb index ee9cd78327a..9af68b4e821 100644 --- a/app/models/project_services/monitoring_service.rb +++ b/app/models/project_services/monitoring_service.rb @@ -9,11 +9,11 @@ class MonitoringService < Service %w() end - def environment_metrics(environment) + def can_query? raise NotImplementedError end - def deployment_metrics(deployment) + def query(_, *_) raise NotImplementedError end end diff --git a/app/models/project_services/prometheus_service.rb b/app/models/project_services/prometheus_service.rb index 58731451429..7a0c9a33e70 100644 --- a/app/models/project_services/prometheus_service.rb +++ b/app/models/project_services/prometheus_service.rb @@ -1,9 +1,5 @@ class PrometheusService < MonitoringService - include ReactiveService - - self.reactive_cache_lease_timeout = 30.seconds - self.reactive_cache_refresh_interval = 30.seconds - self.reactive_cache_lifetime = 1.minute + include PrometheusAdapter # Access to prometheus is directly through the API prop_accessor :api_url @@ -66,63 +62,15 @@ class PrometheusService < MonitoringService # Check we can connect to the Prometheus API def test(*args) - client.ping + Gitlab::PrometheusClient.new(prometheus_client).ping { success: true, result: 'Checked API endpoint' } rescue Gitlab::PrometheusClient::Error => err { success: false, result: err } end - def environment_metrics(environment) - with_reactive_cache(Gitlab::Prometheus::Queries::EnvironmentQuery.name, environment.id, &rename_field(:data, :metrics)) - end - - def deployment_metrics(deployment) - metrics = with_reactive_cache(Gitlab::Prometheus::Queries::DeploymentQuery.name, deployment.environment.id, deployment.id, &rename_field(:data, :metrics)) - metrics&.merge(deployment_time: deployment.created_at.to_i) || {} - end - - def additional_environment_metrics(environment) - with_reactive_cache(Gitlab::Prometheus::Queries::AdditionalMetricsEnvironmentQuery.name, environment.id, &:itself) - end - - def additional_deployment_metrics(deployment) - with_reactive_cache(Gitlab::Prometheus::Queries::AdditionalMetricsDeploymentQuery.name, deployment.environment.id, deployment.id, &:itself) - end - - def matched_metrics - with_reactive_cache(Gitlab::Prometheus::Queries::MatchedMetricsQuery.name, &:itself) - end - - # Cache metrics for specific environment - def calculate_reactive_cache(query_class_name, *args) - return unless active? && project && !project.pending_delete? - - environment_id = args.first - client = client(environment_id) - - data = Kernel.const_get(query_class_name).new(client).query(*args) - { - success: true, - data: data, - last_update: Time.now.utc - } - rescue Gitlab::PrometheusClient::Error => err - { success: false, result: err.message } - end - - def client(environment_id = nil) - if manual_configuration? - Gitlab::PrometheusClient.new(RestClient::Resource.new(api_url)) - else - cluster = cluster_with_prometheus(environment_id) - raise Gitlab::PrometheusClient::Error, "couldn't find cluster with Prometheus installed" unless cluster - - rest_client = client_from_cluster(cluster) - raise Gitlab::PrometheusClient::Error, "couldn't create proxy Prometheus client" unless rest_client - - Gitlab::PrometheusClient.new(rest_client) - end + def prometheus_client + RestClient::Resource.new(api_url) if api_url && manual_configuration? && active? end def prometheus_installed? @@ -134,31 +82,6 @@ class PrometheusService < MonitoringService private - def cluster_with_prometheus(environment_id = nil) - clusters = if environment_id - ::Environment.find_by(id: environment_id).try do |env| - # sort results by descending order based on environment_scope being longer - # thus more closely matching environment slug - project.clusters.enabled.for_environment(env).sort_by { |c| c.environment_scope&.length }.reverse! - end - else - project.clusters.enabled.for_all_environments - end - - clusters&.detect { |cluster| cluster.application_prometheus&.installed? } - end - - def client_from_cluster(cluster) - cluster.application_prometheus.proxy_client - end - - def rename_field(old_field, new_field) - -> (metrics) do - metrics[new_field] = metrics.delete(old_field) - metrics - end - end - def synchronize_service_state! self.active = prometheus_installed? || manual_configuration? -- cgit v1.2.1 From 22e2cad910171bd3ed54ce65da55169c4c6d70b7 Mon Sep 17 00:00:00 2001 From: Pawel Chojnacki Date: Sat, 24 Feb 2018 00:56:50 +0100 Subject: Use deployment platform to find cluster with prometheus application --- app/models/environment.rb | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'app') diff --git a/app/models/environment.rb b/app/models/environment.rb index 2a91bd07b28..966ce17a48a 100644 --- a/app/models/environment.rb +++ b/app/models/environment.rb @@ -233,12 +233,10 @@ class Environment < ActiveRecord::Base end def cluster_prometheus_adapter - # sort results by descending order based on environment_scope being longer - # thus more closely matching environment slug - clusters = project.clusters.enabled.for_environment(self).sort_by { |c| c.environment_scope&.length }.reverse! + cluster = project.deployment_platform&.cluster + return unless cluster&.application_prometheus&.installed? - cluster = clusters&.detect { |cluster| cluster.application_prometheus&.installed? } - cluster&.application_prometheus + cluster.application_prometheus end private -- cgit v1.2.1 From 0feeddaa0f4831e53d8d094b0cbb84222524431a Mon Sep 17 00:00:00 2001 From: Pawel Chojnacki Date: Sat, 24 Feb 2018 01:06:08 +0100 Subject: drop the ! from synchronize_service_state! + remove unused scope --- app/models/clusters/cluster.rb | 2 -- app/models/project_services/prometheus_service.rb | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'app') diff --git a/app/models/clusters/cluster.rb b/app/models/clusters/cluster.rb index 1fd7db30107..5ecbd4cbceb 100644 --- a/app/models/clusters/cluster.rb +++ b/app/models/clusters/cluster.rb @@ -49,8 +49,6 @@ module Clusters scope :enabled, -> { where(enabled: true) } scope :disabled, -> { where(enabled: false) } - scope :for_environment, -> (env) { where(environment_scope: ['*', '', env.slug]) } - def status_name if provider provider.status_name diff --git a/app/models/project_services/prometheus_service.rb b/app/models/project_services/prometheus_service.rb index 7a0c9a33e70..dcaeb65dc32 100644 --- a/app/models/project_services/prometheus_service.rb +++ b/app/models/project_services/prometheus_service.rb @@ -9,7 +9,7 @@ class PrometheusService < MonitoringService validates :api_url, url: true end - before_save :synchronize_service_state! + before_save :synchronize_service_state after_save :clear_reactive_cache! @@ -82,7 +82,7 @@ class PrometheusService < MonitoringService private - def synchronize_service_state! + def synchronize_service_state self.active = prometheus_installed? || manual_configuration? true -- cgit v1.2.1 From 637c9558627655aaf08066371f0a5d50461578be Mon Sep 17 00:00:00 2001 From: Pawel Chojnacki Date: Mon, 26 Feb 2018 12:40:40 +0100 Subject: Fix failing test, when deployment platform is not bound to a cluster. --- app/models/environment.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'app') diff --git a/app/models/environment.rb b/app/models/environment.rb index 966ce17a48a..0c408257499 100644 --- a/app/models/environment.rb +++ b/app/models/environment.rb @@ -233,8 +233,10 @@ class Environment < ActiveRecord::Base end def cluster_prometheus_adapter - cluster = project.deployment_platform&.cluster - return unless cluster&.application_prometheus&.installed? + return unless project.deployment_platform.respond_to?(:cluster) + + cluster = project.deployment_platform.cluster + return unless cluster.application_prometheus&.installed? cluster.application_prometheus end -- cgit v1.2.1 From 2c090539f2dbdbc11c18598c7952a5de497047ea Mon Sep 17 00:00:00 2001 From: Pawel Chojnacki Date: Mon, 26 Feb 2018 19:57:11 +0100 Subject: use deployment_platform DI in environment and revert changes to k8s cert verification policy --- app/models/clusters/platforms/kubernetes.rb | 2 +- app/models/environment.rb | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'app') diff --git a/app/models/clusters/platforms/kubernetes.rb b/app/models/clusters/platforms/kubernetes.rb index 66f629df1b4..7ce8befeeeb 100644 --- a/app/models/clusters/platforms/kubernetes.rb +++ b/app/models/clusters/platforms/kubernetes.rb @@ -141,7 +141,7 @@ module Clusters end def kubeclient_ssl_options - opts = { verify_ssl: OpenSSL::SSL::VERIFY_NONE } + opts = { verify_ssl: OpenSSL::SSL::VERIFY_PEER } if ca_pem.present? opts[:cert_store] = OpenSSL::X509::Store.new diff --git a/app/models/environment.rb b/app/models/environment.rb index 0c408257499..57960a7c3b3 100644 --- a/app/models/environment.rb +++ b/app/models/environment.rb @@ -220,6 +220,10 @@ class Environment < ActiveRecord::Base self.environment_type || self.name end + def deployment_platform + project.deployment_platform + end + def prometheus_adapter @prometheus_adapter ||= if service_prometheus_adapter.can_query? service_prometheus_adapter @@ -233,9 +237,9 @@ class Environment < ActiveRecord::Base end def cluster_prometheus_adapter - return unless project.deployment_platform.respond_to?(:cluster) + return unless deployment_platform.respond_to?(:cluster) - cluster = project.deployment_platform.cluster + cluster = deployment_platform.cluster return unless cluster.application_prometheus&.installed? cluster.application_prometheus -- cgit v1.2.1 From a4308c53e5db594a6e351b143e11ceba6033cdc7 Mon Sep 17 00:00:00 2001 From: Travis Miller Date: Sat, 24 Feb 2018 23:03:29 -0600 Subject: Add project export API entities --- app/models/project.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'app') diff --git a/app/models/project.rb b/app/models/project.rb index ba278a49688..791b69bd9ee 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1567,6 +1567,21 @@ class Project < ActiveRecord::Base Dir.glob("#{export_path}/*export.tar.gz").max_by { |f| File.ctime(f) } end + def export_status + if export_in_progress? + :started + elsif export_project_path + :finished + else + :none + end + end + + def export_in_progress? + shared = Gitlab::ImportExport::Shared.new(relative_path: File.join(disk_path, 'work')) + File.directory?(shared.export_path) + end + def remove_exports return nil unless export_path.present? -- cgit v1.2.1 From c75187df8ce7d376ddc2c7201ce74d45b49fe5d9 Mon Sep 17 00:00:00 2001 From: Travis Miller Date: Sat, 2 Dec 2017 13:49:01 -0600 Subject: Add project export API implementation --- app/models/project.rb | 5 ++--- app/services/projects/import_export/export_service.rb | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'app') diff --git a/app/models/project.rb b/app/models/project.rb index 791b69bd9ee..62a3b655ad1 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1560,7 +1560,7 @@ class Project < ActiveRecord::Base def export_path return nil unless namespace.present? || hashed_storage?(:repository) - File.join(Gitlab::ImportExport.storage_path, disk_path) + Gitlab::ImportExport::Shared.new(self).archive_path end def export_project_path @@ -1578,8 +1578,7 @@ class Project < ActiveRecord::Base end def export_in_progress? - shared = Gitlab::ImportExport::Shared.new(relative_path: File.join(disk_path, 'work')) - File.directory?(shared.export_path) + Gitlab::ImportExport::Shared.new(self).active_export_count > 0 end def remove_exports diff --git a/app/services/projects/import_export/export_service.rb b/app/services/projects/import_export/export_service.rb index fe4e8ea10bf..e26ce3089bb 100644 --- a/app/services/projects/import_export/export_service.rb +++ b/app/services/projects/import_export/export_service.rb @@ -2,7 +2,7 @@ module Projects module ImportExport class ExportService < BaseService def execute(_options = {}) - @shared = Gitlab::ImportExport::Shared.new(relative_path: File.join(project.disk_path, 'work')) + @shared = Gitlab::ImportExport::Shared.new(project) save_all end -- cgit v1.2.1 From 2b176137c9b5617d38ff89b6f8ed4636018916c9 Mon Sep 17 00:00:00 2001 From: Travis Miller Date: Wed, 28 Feb 2018 21:25:54 -0600 Subject: review: instantiate shared import/export object in project method --- app/models/project.rb | 8 ++++++-- app/services/projects/import_export/export_service.rb | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'app') diff --git a/app/models/project.rb b/app/models/project.rb index 62a3b655ad1..190473aa196 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1557,10 +1557,14 @@ class Project < ActiveRecord::Base end end + def import_export + @import_export ||= Gitlab::ImportExport::Shared.new(self) + end + def export_path return nil unless namespace.present? || hashed_storage?(:repository) - Gitlab::ImportExport::Shared.new(self).archive_path + import_export.archive_path end def export_project_path @@ -1578,7 +1582,7 @@ class Project < ActiveRecord::Base end def export_in_progress? - Gitlab::ImportExport::Shared.new(self).active_export_count > 0 + import_export.active_export_count > 0 end def remove_exports diff --git a/app/services/projects/import_export/export_service.rb b/app/services/projects/import_export/export_service.rb index e26ce3089bb..2af228eff05 100644 --- a/app/services/projects/import_export/export_service.rb +++ b/app/services/projects/import_export/export_service.rb @@ -2,7 +2,7 @@ module Projects module ImportExport class ExportService < BaseService def execute(_options = {}) - @shared = Gitlab::ImportExport::Shared.new(project) + @shared = project.import_export save_all end -- cgit v1.2.1 From 8ad9cd5581dafeb7a24da7ed119a30761a0a72fe Mon Sep 17 00:00:00 2001 From: Pawel Chojnacki Date: Thu, 1 Mar 2018 18:14:54 +0100 Subject: Implement PrometheusDeploymentLocator + fix metrics controller --- .../projects/prometheus/metrics_controller.rb | 6 ++--- app/models/concerns/prometheus_adapter_locator.rb | 26 ++++++++++++++++++++++ app/models/environment.rb | 23 ++----------------- 3 files changed, 30 insertions(+), 25 deletions(-) create mode 100644 app/models/concerns/prometheus_adapter_locator.rb (limited to 'app') diff --git a/app/controllers/projects/prometheus/metrics_controller.rb b/app/controllers/projects/prometheus/metrics_controller.rb index 255fbf254fb..ec3c49059e1 100644 --- a/app/controllers/projects/prometheus/metrics_controller.rb +++ b/app/controllers/projects/prometheus/metrics_controller.rb @@ -1,6 +1,8 @@ module Projects module Prometheus class MetricsController < Projects::ApplicationController + include PrometheusAdapterLocator + before_action :authorize_admin_project! before_action :require_prometheus_metrics! @@ -20,10 +22,6 @@ module Projects private - def prometheus_adapter - project.prometheus_service - end - def require_prometheus_metrics! render_404 unless prometheus_adapter.can_query? end diff --git a/app/models/concerns/prometheus_adapter_locator.rb b/app/models/concerns/prometheus_adapter_locator.rb new file mode 100644 index 00000000000..f301eab5c57 --- /dev/null +++ b/app/models/concerns/prometheus_adapter_locator.rb @@ -0,0 +1,26 @@ +module PrometheusAdapterLocator + def deployment_platform + project.deployment_platform + end + + def prometheus_adapter + @prometheus_adapter ||= if service_prometheus_adapter.can_query? + service_prometheus_adapter + else + cluster_prometheus_adapter + end + end + + def service_prometheus_adapter + project.find_or_initialize_service('prometheus') + end + + def cluster_prometheus_adapter + return unless deployment_platform.respond_to?(:cluster) + + cluster = deployment_platform.cluster + return unless cluster.application_prometheus&.installed? + + cluster.application_prometheus + end +end \ No newline at end of file diff --git a/app/models/environment.rb b/app/models/environment.rb index 57960a7c3b3..baba023c92d 100644 --- a/app/models/environment.rb +++ b/app/models/environment.rb @@ -1,4 +1,6 @@ class Environment < ActiveRecord::Base + include PrometheusAdapterLocator + # Used to generate random suffixes for the slug LETTERS = 'a'..'z' NUMBERS = '0'..'9' @@ -224,27 +226,6 @@ class Environment < ActiveRecord::Base project.deployment_platform end - def prometheus_adapter - @prometheus_adapter ||= if service_prometheus_adapter.can_query? - service_prometheus_adapter - else - cluster_prometheus_adapter - end - end - - def service_prometheus_adapter - project.find_or_initialize_service('prometheus') - end - - def cluster_prometheus_adapter - return unless deployment_platform.respond_to?(:cluster) - - cluster = deployment_platform.cluster - return unless cluster.application_prometheus&.installed? - - cluster.application_prometheus - end - private # Slugifying a name may remove the uniqueness guarantee afforded by it being -- cgit v1.2.1 From 273e4142566a053e0628183fbf86ef7b94cb5a66 Mon Sep 17 00:00:00 2001 From: Pawel Chojnacki Date: Thu, 1 Mar 2018 20:20:41 +0100 Subject: add missing newline --- app/models/concerns/prometheus_adapter_locator.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app') diff --git a/app/models/concerns/prometheus_adapter_locator.rb b/app/models/concerns/prometheus_adapter_locator.rb index f301eab5c57..d8a3ed0de2d 100644 --- a/app/models/concerns/prometheus_adapter_locator.rb +++ b/app/models/concerns/prometheus_adapter_locator.rb @@ -23,4 +23,4 @@ module PrometheusAdapterLocator cluster.application_prometheus end -end \ No newline at end of file +end -- cgit v1.2.1 From dd071c4b6e9754a0abeec45ab2040d9e2d5a62b8 Mon Sep 17 00:00:00 2001 From: Felipe Artur Date: Mon, 19 Feb 2018 16:06:16 -0300 Subject: Bring one group board to CE --- .../javascripts/boards/components/board_card.vue | 5 + .../javascripts/boards/components/board_list.vue | 7 ++ .../boards/components/board_new_issue.vue | 110 +++++++++++------- .../boards/components/issue_card_inner.js | 14 ++- .../boards/components/project_select.vue | 127 +++++++++++++++++++++ .../boards/components/sidebar/remove_issue.js | 8 +- .../javascripts/boards/filtered_search_boards.js | 1 + app/assets/javascripts/boards/index.js | 5 +- .../boards/mixins/sortable_default_options.js | 13 +-- app/assets/javascripts/boards/models/issue.js | 10 +- app/assets/javascripts/boards/models/project.js | 6 + .../javascripts/pages/groups/boards/index.js | 9 ++ app/assets/javascripts/sortable/sortable_config.js | 7 ++ app/controllers/boards/issues_controller.rb | 18 ++- app/controllers/concerns/boards_responses.rb | 44 ++++++- app/controllers/groups/boards_controller.rb | 27 +++++ app/controllers/groups/labels_controller.rb | 16 ++- app/helpers/boards_helper.rb | 30 +++-- app/helpers/form_helper.rb | 2 +- app/helpers/groups_helper.rb | 2 +- app/models/board.rb | 8 +- app/models/group.rb | 2 + app/models/label.rb | 1 + app/models/namespace.rb | 5 + app/models/project.rb | 5 +- app/policies/group_policy.rb | 7 +- app/services/boards/issues/list_service.rb | 6 +- app/services/boards/issues/move_service.rb | 4 +- app/services/boards/lists/create_service.rb | 6 +- app/views/groups/boards/index.html.haml | 1 + app/views/groups/boards/show.html.haml | 1 + app/views/layouts/nav/sidebar/_group.html.haml | 9 +- app/views/shared/boards/_show.html.haml | 4 +- .../shared/boards/components/_board.html.haml | 1 + app/views/shared/issuable/_search_bar.html.haml | 3 +- 35 files changed, 440 insertions(+), 84 deletions(-) create mode 100644 app/assets/javascripts/boards/components/project_select.vue create mode 100644 app/assets/javascripts/boards/models/project.js create mode 100644 app/assets/javascripts/pages/groups/boards/index.js create mode 100644 app/assets/javascripts/sortable/sortable_config.js create mode 100644 app/controllers/groups/boards_controller.rb create mode 100644 app/views/groups/boards/index.html.haml create mode 100644 app/views/groups/boards/show.html.haml (limited to 'app') diff --git a/app/assets/javascripts/boards/components/board_card.vue b/app/assets/javascripts/boards/components/board_card.vue index 23fec503586..84885ca9306 100644 --- a/app/assets/javascripts/boards/components/board_card.vue +++ b/app/assets/javascripts/boards/components/board_card.vue @@ -1,4 +1,5 @@ + diff --git a/app/assets/javascripts/boards/components/issue_card_inner.js b/app/assets/javascripts/boards/components/issue_card_inner.js index bf474879024..fc2bad2415f 100644 --- a/app/assets/javascripts/boards/components/issue_card_inner.js +++ b/app/assets/javascripts/boards/components/issue_card_inner.js @@ -31,6 +31,10 @@ gl.issueBoards.IssueCardInner = Vue.extend({ required: false, default: false, }, + groupId: { + type: Number, + required: false, + }, }, data() { return { @@ -64,7 +68,13 @@ gl.issueBoards.IssueCardInner = Vue.extend({ return this.issue.assignees.length > this.numberOverLimit; }, cardUrl() { - return `${this.issueLinkBase}/${this.issue.iid}`; + let baseUrl = this.issueLinkBase; + + if (this.groupId && this.issue.project) { + baseUrl = this.issueLinkBase.replace(':project_path', this.issue.project.path); + } + + return `${baseUrl}/${this.issue.iid}`; }, issueId() { if (this.issue.iid) { @@ -148,7 +158,7 @@ gl.issueBoards.IssueCardInner = Vue.extend({ class="card-number" v-if="issueId" > - {{ issueId }} + {{ issueId }}
diff --git a/app/assets/javascripts/boards/components/project_select.vue b/app/assets/javascripts/boards/components/project_select.vue new file mode 100644 index 00000000000..d99b222c305 --- /dev/null +++ b/app/assets/javascripts/boards/components/project_select.vue @@ -0,0 +1,127 @@ + + + diff --git a/app/assets/javascripts/boards/components/sidebar/remove_issue.js b/app/assets/javascripts/boards/components/sidebar/remove_issue.js index 0ae32bb4d0a..09c683ff621 100644 --- a/app/assets/javascripts/boards/components/sidebar/remove_issue.js +++ b/app/assets/javascripts/boards/components/sidebar/remove_issue.js @@ -24,7 +24,7 @@ gl.issueBoards.RemoveIssueBtn = Vue.extend({ }, computed: { updateUrl() { - return this.issueUpdate; + return this.issueUpdate.replace(':project_path', this.issue.project.path); }, }, methods: { @@ -32,17 +32,21 @@ gl.issueBoards.RemoveIssueBtn = Vue.extend({ const issue = this.issue; const lists = issue.getLists(); const listLabelIds = lists.map(list => list.label.id); - let labelIds = this.issue.labels + + let labelIds = issue.labels .map(label => label.id) .filter(id => !listLabelIds.includes(id)); if (labelIds.length === 0) { labelIds = ['']; } + const data = { issue: { label_ids: labelIds, }, }; + + // Post the remove data Vue.http.patch(this.updateUrl, data).catch(() => { Flash(__('Failed to remove issue from board, please try again.')); diff --git a/app/assets/javascripts/boards/filtered_search_boards.js b/app/assets/javascripts/boards/filtered_search_boards.js index 57a7cc4ca30..fb40b9f5565 100644 --- a/app/assets/javascripts/boards/filtered_search_boards.js +++ b/app/assets/javascripts/boards/filtered_search_boards.js @@ -6,6 +6,7 @@ export default class FilteredSearchBoards extends FilteredSearchManager { constructor(store, updateUrl = false, cantEdit = []) { super({ page: 'boards', + stateFiltersSelector: '.issues-state-filters', }); this.store = store; diff --git a/app/assets/javascripts/boards/index.js b/app/assets/javascripts/boards/index.js index 8e31f1865f0..b8749a13f68 100644 --- a/app/assets/javascripts/boards/index.js +++ b/app/assets/javascripts/boards/index.js @@ -13,6 +13,7 @@ import './models/issue'; import './models/label'; import './models/list'; import './models/milestone'; +import './models/project'; import './models/assignee'; import './stores/boards_store'; import './stores/modal_store'; @@ -89,7 +90,7 @@ export default () => { sidebarEventHub.$off('toggleSubscription', this.toggleSubscription); }, mounted () { - this.filterManager = new FilteredSearchBoards(Store.filter, true); + this.filterManager = new FilteredSearchBoards(Store.filter, true, Store.cantEdit); this.filterManager.setup(); Store.disabled = this.disabled; @@ -179,6 +180,7 @@ export default () => { return { modal: ModalStore.store, store: Store.state, + canAdminList: this.$options.el.hasAttribute('data-can-admin-list'), }; }, computed: { @@ -232,6 +234,7 @@ export default () => { :class="{ 'disabled': disabled }" :title="tooltipTitle" :aria-disabled="disabled" + v-if="canAdminList" @click="openModal"> Add issues diff --git a/app/assets/javascripts/boards/mixins/sortable_default_options.js b/app/assets/javascripts/boards/mixins/sortable_default_options.js index 38a0eb12f92..5e31c6314b2 100644 --- a/app/assets/javascripts/boards/mixins/sortable_default_options.js +++ b/app/assets/javascripts/boards/mixins/sortable_default_options.js @@ -1,6 +1,8 @@ /* eslint-disable no-unused-vars, no-mixed-operators, comma-dangle */ /* global DocumentTouch */ +import sortableConfig from '../../sortable/sortable_config'; + window.gl = window.gl || {}; window.gl.issueBoards = window.gl.issueBoards || {}; @@ -18,19 +20,14 @@ gl.issueBoards.onEnd = () => { gl.issueBoards.touchEnabled = ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch; gl.issueBoards.getBoardSortableDefaultOptions = (obj) => { - const defaultSortOptions = { - animation: 200, - forceFallback: true, - fallbackClass: 'is-dragging', - fallbackOnBody: true, - ghostClass: 'is-ghost', + const defaultSortOptions = Object.assign({}, sortableConfig, { filter: '.board-delete, .btn', delay: gl.issueBoards.touchEnabled ? 100 : 0, scrollSensitivity: gl.issueBoards.touchEnabled ? 60 : 100, scrollSpeed: 20, onStart: gl.issueBoards.onStart, - onEnd: gl.issueBoards.onEnd - }; + onEnd: gl.issueBoards.onEnd, + }); Object.keys(obj).forEach((key) => { defaultSortOptions[key] = obj[key]; }); return defaultSortOptions; diff --git a/app/assets/javascripts/boards/models/issue.js b/app/assets/javascripts/boards/models/issue.js index 3bfb6d39ad5..4c5079efc8b 100644 --- a/app/assets/javascripts/boards/models/issue.js +++ b/app/assets/javascripts/boards/models/issue.js @@ -4,6 +4,7 @@ /* global ListAssignee */ import Vue from 'vue'; +import IssueProject from './project'; class ListIssue { constructor (obj, defaultAvatar) { @@ -23,6 +24,12 @@ class ListIssue { this.isLoading = {}; this.sidebarInfoEndpoint = obj.issue_sidebar_endpoint; this.toggleSubscriptionEndpoint = obj.toggle_subscription_endpoint; + this.milestone_id = obj.milestone_id; + this.project_id = obj.project_id; + + if (obj.project) { + this.project = new IssueProject(obj.project); + } if (obj.milestone) { this.milestone = new ListMilestone(obj.milestone); @@ -105,7 +112,8 @@ class ListIssue { data.issue.label_ids = ['']; } - return Vue.http.patch(url, data); + const projectPath = this.project ? this.project.path : ''; + return Vue.http.patch(url.replace(':project_path', projectPath), data); } } diff --git a/app/assets/javascripts/boards/models/project.js b/app/assets/javascripts/boards/models/project.js new file mode 100644 index 00000000000..a3d5c7af7ac --- /dev/null +++ b/app/assets/javascripts/boards/models/project.js @@ -0,0 +1,6 @@ +export default class IssueProject { + constructor(obj) { + this.id = obj.id; + this.path = obj.path; + } +} diff --git a/app/assets/javascripts/pages/groups/boards/index.js b/app/assets/javascripts/pages/groups/boards/index.js new file mode 100644 index 00000000000..5cfe8723204 --- /dev/null +++ b/app/assets/javascripts/pages/groups/boards/index.js @@ -0,0 +1,9 @@ +import UsersSelect from '~/users_select'; +import ShortcutsNavigation from '~/shortcuts_navigation'; +import initBoards from '~/boards'; + +document.addEventListener('DOMContentLoaded', () => { + new UsersSelect(); // eslint-disable-line no-new + new ShortcutsNavigation(); // eslint-disable-line no-new + initBoards(); +}); diff --git a/app/assets/javascripts/sortable/sortable_config.js b/app/assets/javascripts/sortable/sortable_config.js new file mode 100644 index 00000000000..43ef5d66422 --- /dev/null +++ b/app/assets/javascripts/sortable/sortable_config.js @@ -0,0 +1,7 @@ +export default { + animation: 200, + forceFallback: true, + fallbackClass: 'is-dragging', + fallbackOnBody: true, + ghostClass: 'is-ghost', +}; diff --git a/app/controllers/boards/issues_controller.rb b/app/controllers/boards/issues_controller.rb index 352f12a89fd..35571fa9603 100644 --- a/app/controllers/boards/issues_controller.rb +++ b/app/controllers/boards/issues_controller.rb @@ -1,12 +1,14 @@ module Boards class IssuesController < Boards::ApplicationController include BoardsResponses + include ControllerWithCrossProjectAccessCheck + + requires_cross_project_access if: -> { board&.group_board? } before_action :whitelist_query_limiting, only: [:index, :update] before_action :authorize_read_issue, only: [:index] before_action :authorize_create_issue, only: [:create] before_action :authorize_update_issue, only: [:update] - skip_before_action :authenticate_user!, only: [:index] def index issues = Boards::Issues::ListService.new(board_parent, current_user, filter_params).execute @@ -64,11 +66,21 @@ module Boards end def issues_finder - IssuesFinder.new(current_user, project_id: board_parent.id) + if board.group_board? + IssuesFinder.new(current_user, group_id: board_parent.id) + else + IssuesFinder.new(current_user, project_id: board_parent.id) + end end def project - board_parent + @project ||= begin + if board.group_board? + Project.find(issue_params[:project_id]) + else + board_parent + end + end end def move_params diff --git a/app/controllers/concerns/boards_responses.rb b/app/controllers/concerns/boards_responses.rb index a145049dc7d..da830ec2cb1 100644 --- a/app/controllers/concerns/boards_responses.rb +++ b/app/controllers/concerns/boards_responses.rb @@ -1,10 +1,46 @@ module BoardsResponses + include Gitlab::Utils::StrongMemoize + + def board_params + params.require(:board).permit(:name, :weight, :milestone_id, :assignee_id, label_ids: []) + end + + def parent + strong_memoize(:parent) do + group? ? group : project + end + end + + def boards_path + if group? + group_boards_path(parent) + else + project_boards_path(parent) + end + end + + def board_path(board) + if group? + group_board_path(parent, board) + else + project_board_path(parent, board) + end + end + + def group? + instance_variable_defined?(:@group) + end + def authorize_read_list - authorize_action_for!(board.parent, :read_list) + ability = board.group_board? ? :read_group : :read_list + + authorize_action_for!(board.parent, ability) end def authorize_read_issue - authorize_action_for!(board.parent, :read_issue) + ability = board.group_board? ? :read_group : :read_issue + + authorize_action_for!(board.parent, ability) end def authorize_update_issue @@ -31,6 +67,10 @@ module BoardsResponses respond_with(@board) # rubocop:disable Gitlab/ModuleWithInstanceVariables end + def serialize_as_json(resource) + resource.as_json(only: [:id]) + end + def respond_with(resource) respond_to do |format| format.html diff --git a/app/controllers/groups/boards_controller.rb b/app/controllers/groups/boards_controller.rb new file mode 100644 index 00000000000..7c2016f0326 --- /dev/null +++ b/app/controllers/groups/boards_controller.rb @@ -0,0 +1,27 @@ +class Groups::BoardsController < Groups::ApplicationController + include BoardsResponses + + before_action :assign_endpoint_vars + + def index + @boards = Boards::ListService.new(group, current_user).execute + + respond_with_boards + end + + def show + @board = group.boards.find(params[:id]) + + respond_with_board + end + + def assign_endpoint_vars + @boards_endpoint = group_boards_url(group) + @namespace_path = group.to_param + @labels_endpoint = group_labels_url(group) + end + + def serialize_as_json(resource) + resource.as_json(only: [:id]) + end +end diff --git a/app/controllers/groups/labels_controller.rb b/app/controllers/groups/labels_controller.rb index ac1d97dc54a..58be330f466 100644 --- a/app/controllers/groups/labels_controller.rb +++ b/app/controllers/groups/labels_controller.rb @@ -35,10 +35,18 @@ class Groups::LabelsController < Groups::ApplicationController def create @label = Labels::CreateService.new(label_params).execute(group: group) - if @label.valid? - redirect_to group_labels_path(@group) - else - render :new + respond_to do |format| + format.html do + if @label.valid? + redirect_to group_labels_path(@group) + else + render :new + end + end + + format.json do + render json: LabelSerializer.new.represent_appearance(@label) + end end end diff --git a/app/helpers/boards_helper.rb b/app/helpers/boards_helper.rb index 12b3d9bac1a..8304a83a952 100644 --- a/app/helpers/boards_helper.rb +++ b/app/helpers/boards_helper.rb @@ -17,23 +17,37 @@ module BoardsHelper end def build_issue_link_base - project_issues_path(@project) + if board.group_board? + "#{group_path(@board.group)}/:project_path/issues" + else + project_issues_path(@project) + end end def board_base_url - project_boards_path(@project) + if board.group_board? + group_boards_url(@group) + else + project_boards_path(@project) + end end def multiple_boards_available? - current_board_parent.multiple_issue_boards_available?(current_user) + current_board_parent.multiple_issue_boards_available? end def current_board_path(board) - @current_board_path ||= project_board_path(current_board_parent, board) + @current_board_path ||= begin + if board.group_board? + group_board_path(current_board_parent, board) + else + project_board_path(current_board_parent, board) + end + end end def current_board_parent - @current_board_parent ||= @project + @current_board_parent ||= @group || @project end def can_admin_issue? @@ -47,7 +61,8 @@ module BoardsHelper labels: labels_filter_path(true), labels_endpoint: @labels_endpoint, namespace_path: @namespace_path, - project_path: @project&.try(:path) + project_path: @project&.path, + group_path: @group&.path } end @@ -59,7 +74,8 @@ module BoardsHelper field_name: 'issue[assignee_ids][]', first_user: current_user&.username, current_user: 'true', - project_id: @project&.try(:id), + project_id: @project&.id, + group_id: @group&.id, null_user: 'true', multi_select: 'true', 'dropdown-header': dropdown_options[:data][:'dropdown-header'], diff --git a/app/helpers/form_helper.rb b/app/helpers/form_helper.rb index e26ce6da030..905e2002592 100644 --- a/app/helpers/form_helper.rb +++ b/app/helpers/form_helper.rb @@ -27,7 +27,7 @@ module FormHelper first_user: current_user&.username, null_user: true, current_user: true, - project_id: @project.id, + project_id: @project&.id, field_name: 'issue[assignee_ids][]', default_label: 'Unassigned', 'max-select': 1, diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb index 7910de73c52..796623041bb 100644 --- a/app/helpers/groups_helper.rb +++ b/app/helpers/groups_helper.rb @@ -129,7 +129,7 @@ module GroupsHelper links = [:overview, :group_members] if can?(current_user, :read_cross_project) - links += [:activity, :issues, :labels, :milestones, :merge_requests] + links += [:activity, :issues, :labels, :milestones, :merge_requests, :boards] end if can?(current_user, :admin_group, @group) diff --git a/app/models/board.rb b/app/models/board.rb index 5bb7d3d3722..3cede6fc99a 100644 --- a/app/models/board.rb +++ b/app/models/board.rb @@ -1,20 +1,22 @@ class Board < ActiveRecord::Base + belongs_to :group belongs_to :project has_many :lists, -> { order(:list_type, :position) }, dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent validates :project, presence: true, if: :project_needed? + validates :group, presence: true, unless: :project def project_needed? - true + !group end def parent - project + @parent ||= group || project end def group_board? - false + group_id.present? end def backlog_list diff --git a/app/models/group.rb b/app/models/group.rb index 75bf013ecd2..32a0bd0c70b 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -31,6 +31,8 @@ class Group < Namespace has_many :uploads, as: :model, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent + has_many :boards + accepts_nested_attributes_for :variables, allow_destroy: true validate :visibility_level_allowed_by_projects diff --git a/app/models/label.rb b/app/models/label.rb index 7538f2d8718..de7f1d56c64 100644 --- a/app/models/label.rb +++ b/app/models/label.rb @@ -35,6 +35,7 @@ class Label < ActiveRecord::Base scope :templates, -> { where(template: true) } scope :with_title, ->(title) { where(title: title) } scope :with_lists_and_board, -> { joins(lists: :board).merge(List.movable) } + scope :on_group_boards, ->(group_id) { with_lists_and_board.where(boards: { group_id: group_id }) } scope :on_project_boards, ->(project_id) { with_lists_and_board.where(boards: { project_id: project_id }) } def self.prioritized(project) diff --git a/app/models/namespace.rb b/app/models/namespace.rb index db274ea8172..37e5b4615ce 100644 --- a/app/models/namespace.rb +++ b/app/models/namespace.rb @@ -222,6 +222,11 @@ class Namespace < ActiveRecord::Base has_parent? end + # Overriden on EE module + def multiple_issue_boards_available? + false + end + def full_path_was if parent_id_was.nil? path_was diff --git a/app/models/project.rb b/app/models/project.rb index ba278a49688..5206a7d4d25 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1695,8 +1695,9 @@ class Project < ActiveRecord::Base end end - def multiple_issue_boards_available?(user) - feature_available?(:multiple_issue_boards, user) + # Overridden on EE module + def multiple_issue_boards_available? + false end def issue_board_milestone_available?(user = nil) diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb index f0bcba588a2..c9cb730c4e9 100644 --- a/app/policies/group_policy.rb +++ b/app/policies/group_policy.rb @@ -48,7 +48,12 @@ class GroupPolicy < BasePolicy rule { has_access }.enable :read_namespace rule { developer }.enable :admin_milestones - rule { reporter }.enable :admin_label + + rule { reporter }.policy do + enable :admin_label + enable :admin_list + enable :admin_issue + end rule { master }.policy do enable :create_projects diff --git a/app/services/boards/issues/list_service.rb b/app/services/boards/issues/list_service.rb index 6078fe38064..ecd74b74f8a 100644 --- a/app/services/boards/issues/list_service.rb +++ b/app/services/boards/issues/list_service.rb @@ -40,7 +40,11 @@ module Boards end def set_parent - params[:project_id] = parent.id + if parent.is_a?(Group) + params[:group_id] = parent.id + else + params[:project_id] = parent.id + end end def set_state diff --git a/app/services/boards/issues/move_service.rb b/app/services/boards/issues/move_service.rb index 797d6df7c1a..15fed7d17c1 100644 --- a/app/services/boards/issues/move_service.rb +++ b/app/services/boards/issues/move_service.rb @@ -60,8 +60,10 @@ module Boards label_ids = if moving_to_list.movable? moving_from_list.label_id + elsif board.group_board? + ::Label.on_group_boards(parent.id).pluck(:label_id) else - Label.on_project_boards(parent.id).pluck(:label_id) + ::Label.on_project_boards(parent.id).pluck(:label_id) end Array(label_ids).compact diff --git a/app/services/boards/lists/create_service.rb b/app/services/boards/lists/create_service.rb index 183556a1d6b..bebc90c7a8d 100644 --- a/app/services/boards/lists/create_service.rb +++ b/app/services/boards/lists/create_service.rb @@ -12,7 +12,11 @@ module Boards private def available_labels_for(board) - LabelsFinder.new(current_user, project_id: parent.id).execute + if board.group_board? + parent.labels + else + LabelsFinder.new(current_user, project_id: parent.id).execute + end end def next_position(board) diff --git a/app/views/groups/boards/index.html.haml b/app/views/groups/boards/index.html.haml new file mode 100644 index 00000000000..bb56769bd3f --- /dev/null +++ b/app/views/groups/boards/index.html.haml @@ -0,0 +1 @@ += render "shared/boards/show", board: @boards.first diff --git a/app/views/groups/boards/show.html.haml b/app/views/groups/boards/show.html.haml new file mode 100644 index 00000000000..92838fa4b11 --- /dev/null +++ b/app/views/groups/boards/show.html.haml @@ -0,0 +1 @@ += render "shared/boards/show", board: @board, group: true diff --git a/app/views/layouts/nav/sidebar/_group.html.haml b/app/views/layouts/nav/sidebar/_group.html.haml index b520f28123f..5ea19c9882d 100644 --- a/app/views/layouts/nav/sidebar/_group.html.haml +++ b/app/views/layouts/nav/sidebar/_group.html.haml @@ -1,6 +1,6 @@ - issues_count = group_issues_count(state: 'opened') - merge_requests_count = group_merge_requests_count(state: 'opened') -- issues_sub_menu_items = ['groups#issues', 'labels#index', 'milestones#index'] +- issues_sub_menu_items = ['groups#issues', 'labels#index', 'milestones#index', 'boards#index', 'boards#show'] .nav-sidebar{ class: ("sidebar-collapsed-desktop" if collapsed_sidebar?) } .nav-sidebar-inner-scroll @@ -51,12 +51,19 @@ %strong.fly-out-top-item-name #{ _('Issues') } %span.badge.count.issue_counter.fly-out-badge= number_with_delimiter(issues_count) + %li.divider.fly-out-top-item = nav_link(path: 'groups#issues', html_options: { class: 'home' }) do = link_to issues_group_path(@group), title: 'List' do %span List + - if group_sidebar_link?(:boards) + = nav_link(path: ['boards#index', 'boards#show']) do + = link_to group_boards_path(@group), title: boards_link_text do + %span + = boards_link_text + - if group_sidebar_link?(:labels) = nav_link(path: 'labels#index') do = link_to group_labels_path(@group), title: 'Labels' do diff --git a/app/views/shared/boards/_show.html.haml b/app/views/shared/boards/_show.html.haml index 014b8de1dc9..3ac4245a61b 100644 --- a/app/views/shared/boards/_show.html.haml +++ b/app/views/shared/boards/_show.html.haml @@ -1,3 +1,5 @@ +- board = local_assigns.fetch(:board, nil) +- group = local_assigns.fetch(:group, false) - @no_breadcrumb_container = true - @no_container = true - @content_class = "issue-boards-content" @@ -27,7 +29,7 @@ ":root-path" => "rootPath", ":board-id" => "boardId", ":key" => "_uid" } - = render "shared/boards/components/sidebar" + = render "shared/boards/components/sidebar", group: group - if @project %board-add-issues-modal{ "new-issue-path" => new_project_issue_path(@project), "milestone-path" => milestones_filter_dropdown_path, diff --git a/app/views/shared/boards/components/_board.html.haml b/app/views/shared/boards/components/_board.html.haml index c687e66fd43..2e9ad380012 100644 --- a/app/views/shared/boards/components/_board.html.haml +++ b/app/views/shared/boards/components/_board.html.haml @@ -42,6 +42,7 @@ ":disabled" => "disabled", ":issue-link-base" => "issueLinkBase", ":root-path" => "rootPath", + ":groupId" => ((current_board_parent.id if @group) || 'null'), "ref" => "board-list" } - if can?(current_user, :admin_list, current_board_parent) %board-blank-state{ "v-if" => 'list.id == "blank"' } diff --git a/app/views/shared/issuable/_search_bar.html.haml b/app/views/shared/issuable/_search_bar.html.haml index fabb17c7340..fc6f71ef60f 100644 --- a/app/views/shared/issuable/_search_bar.html.haml +++ b/app/views/shared/issuable/_search_bar.html.haml @@ -112,6 +112,7 @@ - if can?(current_user, :admin_label, board.parent) = render partial: "shared/issuable/label_page_create" = dropdown_loading - #js-add-issues-btn.prepend-left-10 + - if @project + #js-add-issues-btn.prepend-left-10{ data: { can_admin_list: can?(current_user, :admin_list, @project) } } - elsif type != :boards_modal = render 'shared/sort_dropdown' -- cgit v1.2.1 From 9946d0813c8e377ecf22552c4af075e563144712 Mon Sep 17 00:00:00 2001 From: Felipe Artur Date: Mon, 5 Mar 2018 11:39:24 -0300 Subject: Address review comments --- app/controllers/boards/issues_controller.rb | 13 ++++++------- app/helpers/boards_helper.rb | 12 +++++------- app/helpers/groups_helper.rb | 2 +- 3 files changed, 12 insertions(+), 15 deletions(-) (limited to 'app') diff --git a/app/controllers/boards/issues_controller.rb b/app/controllers/boards/issues_controller.rb index 35571fa9603..19dbee84c11 100644 --- a/app/controllers/boards/issues_controller.rb +++ b/app/controllers/boards/issues_controller.rb @@ -9,6 +9,7 @@ module Boards before_action :authorize_read_issue, only: [:index] before_action :authorize_create_issue, only: [:create] before_action :authorize_update_issue, only: [:update] + skip_before_action :authenticate_user!, only: [:index] def index issues = Boards::Issues::ListService.new(board_parent, current_user, filter_params).execute @@ -74,13 +75,11 @@ module Boards end def project - @project ||= begin - if board.group_board? - Project.find(issue_params[:project_id]) - else - board_parent - end - end + @project ||= if board.group_board? + Project.find(issue_params[:project_id]) + else + board_parent + end end def move_params diff --git a/app/helpers/boards_helper.rb b/app/helpers/boards_helper.rb index 8304a83a952..275e892b2e6 100644 --- a/app/helpers/boards_helper.rb +++ b/app/helpers/boards_helper.rb @@ -37,13 +37,11 @@ module BoardsHelper end def current_board_path(board) - @current_board_path ||= begin - if board.group_board? - group_board_path(current_board_parent, board) - else - project_board_path(current_board_parent, board) - end - end + @current_board_path ||= if board.group_board? + group_board_path(current_board_parent, board) + else + project_board_path(current_board_parent, board) + end end def current_board_parent diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb index 796623041bb..16eceb3f48f 100644 --- a/app/helpers/groups_helper.rb +++ b/app/helpers/groups_helper.rb @@ -129,7 +129,7 @@ module GroupsHelper links = [:overview, :group_members] if can?(current_user, :read_cross_project) - links += [:activity, :issues, :labels, :milestones, :merge_requests, :boards] + links += [:activity, :issues, :boards, :labels, :milestones, :merge_requests] end if can?(current_user, :admin_group, @group) -- cgit v1.2.1 From 5ceec83a0154e513480a9bb08e252371bf7886c6 Mon Sep 17 00:00:00 2001 From: Pawel Chojnacki Date: Mon, 5 Mar 2018 19:34:59 +0100 Subject: Implemente Prometheus:AdapterService --- .../projects/prometheus/metrics_controller.rb | 6 ++-- app/models/concerns/prometheus_adapter_locator.rb | 26 ---------------- app/models/environment.rb | 6 ++-- app/services/prometheus/adapter_service.rb | 36 ++++++++++++++++++++++ 4 files changed, 44 insertions(+), 30 deletions(-) delete mode 100644 app/models/concerns/prometheus_adapter_locator.rb create mode 100644 app/services/prometheus/adapter_service.rb (limited to 'app') diff --git a/app/controllers/projects/prometheus/metrics_controller.rb b/app/controllers/projects/prometheus/metrics_controller.rb index ec3c49059e1..523abce35fb 100644 --- a/app/controllers/projects/prometheus/metrics_controller.rb +++ b/app/controllers/projects/prometheus/metrics_controller.rb @@ -1,8 +1,6 @@ module Projects module Prometheus class MetricsController < Projects::ApplicationController - include PrometheusAdapterLocator - before_action :authorize_admin_project! before_action :require_prometheus_metrics! @@ -22,6 +20,10 @@ module Projects private + def prometheus_adapter + @prometheus_adapter ||= Prometheus::AdapterService.new(project).prometheus_adapter + end + def require_prometheus_metrics! render_404 unless prometheus_adapter.can_query? end diff --git a/app/models/concerns/prometheus_adapter_locator.rb b/app/models/concerns/prometheus_adapter_locator.rb deleted file mode 100644 index d8a3ed0de2d..00000000000 --- a/app/models/concerns/prometheus_adapter_locator.rb +++ /dev/null @@ -1,26 +0,0 @@ -module PrometheusAdapterLocator - def deployment_platform - project.deployment_platform - end - - def prometheus_adapter - @prometheus_adapter ||= if service_prometheus_adapter.can_query? - service_prometheus_adapter - else - cluster_prometheus_adapter - end - end - - def service_prometheus_adapter - project.find_or_initialize_service('prometheus') - end - - def cluster_prometheus_adapter - return unless deployment_platform.respond_to?(:cluster) - - cluster = deployment_platform.cluster - return unless cluster.application_prometheus&.installed? - - cluster.application_prometheus - end -end diff --git a/app/models/environment.rb b/app/models/environment.rb index baba023c92d..24d4f1d8761 100644 --- a/app/models/environment.rb +++ b/app/models/environment.rb @@ -1,6 +1,4 @@ class Environment < ActiveRecord::Base - include PrometheusAdapterLocator - # Used to generate random suffixes for the slug LETTERS = 'a'..'z' NUMBERS = '0'..'9' @@ -159,6 +157,10 @@ class Environment < ActiveRecord::Base prometheus_adapter.query(:additional_metrics_environment, self) if has_metrics? end + def prometheus_adapter + @prometheus_adapter ||= Prometheus::AdapterService.new(project, deployment_platform).prometheus_adapter + end + def slug super.presence || generate_slug end diff --git a/app/services/prometheus/adapter_service.rb b/app/services/prometheus/adapter_service.rb new file mode 100644 index 00000000000..4504d2ccfe6 --- /dev/null +++ b/app/services/prometheus/adapter_service.rb @@ -0,0 +1,36 @@ +module Prometheus + class AdapterService + def initialize(project, deployment_platform = nil) + @project = project + + @deployment_platform = if deployment_platform + deployment_platform + else + project.deployment_platform + end + end + + attr_reader :deployment_platform, :project + + def prometheus_adapter + @prometheus_adapter ||= if service_prometheus_adapter.can_query? + service_prometheus_adapter + else + cluster_prometheus_adapter + end + end + + def service_prometheus_adapter + project.find_or_initialize_service('prometheus') + end + + def cluster_prometheus_adapter + return unless deployment_platform.respond_to?(:cluster) + + cluster = deployment_platform.cluster + return unless cluster.application_prometheus&.installed? + + cluster.application_prometheus + end + end +end -- cgit v1.2.1 From 6d1c5014e96d96ad44fed71dd99bf6c1d4af3cec Mon Sep 17 00:00:00 2001 From: Travis Miller Date: Mon, 5 Mar 2018 13:53:40 -0600 Subject: review: rename import_export to import_export_shared --- app/models/project.rb | 8 ++++---- app/services/projects/import_export/export_service.rb | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'app') diff --git a/app/models/project.rb b/app/models/project.rb index 190473aa196..666614bb3d9 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1557,14 +1557,14 @@ class Project < ActiveRecord::Base end end - def import_export - @import_export ||= Gitlab::ImportExport::Shared.new(self) + def import_export_shared + @import_export_shared ||= Gitlab::ImportExport::Shared.new(self) end def export_path return nil unless namespace.present? || hashed_storage?(:repository) - import_export.archive_path + import_export_shared.archive_path end def export_project_path @@ -1582,7 +1582,7 @@ class Project < ActiveRecord::Base end def export_in_progress? - import_export.active_export_count > 0 + import_export_shared.active_export_count > 0 end def remove_exports diff --git a/app/services/projects/import_export/export_service.rb b/app/services/projects/import_export/export_service.rb index 2af228eff05..af41ce82f65 100644 --- a/app/services/projects/import_export/export_service.rb +++ b/app/services/projects/import_export/export_service.rb @@ -2,7 +2,7 @@ module Projects module ImportExport class ExportService < BaseService def execute(_options = {}) - @shared = project.import_export + @shared = project.import_export_shared save_all end -- cgit v1.2.1 From b53356546dc54a6674eda8fa2d4f730a70f77206 Mon Sep 17 00:00:00 2001 From: Pawel Chojnacki Date: Mon, 5 Mar 2018 21:02:26 +0100 Subject: Check if prometheus_adapter is properly called --- app/controllers/projects/prometheus/metrics_controller.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'app') diff --git a/app/controllers/projects/prometheus/metrics_controller.rb b/app/controllers/projects/prometheus/metrics_controller.rb index 523abce35fb..51b29855bcf 100644 --- a/app/controllers/projects/prometheus/metrics_controller.rb +++ b/app/controllers/projects/prometheus/metrics_controller.rb @@ -21,9 +21,10 @@ module Projects private def prometheus_adapter - @prometheus_adapter ||= Prometheus::AdapterService.new(project).prometheus_adapter + @prometheus_adapter ||= ::Prometheus::AdapterService.new(project).prometheus_adapter end + def require_prometheus_metrics! render_404 unless prometheus_adapter.can_query? end -- cgit v1.2.1 From bd684b70ebbc7f3dfedc4fa29485e67e13ca4731 Mon Sep 17 00:00:00 2001 From: Pawel Chojnacki Date: Mon, 5 Mar 2018 23:32:08 +0100 Subject: one space too far --- app/controllers/projects/prometheus/metrics_controller.rb | 1 - 1 file changed, 1 deletion(-) (limited to 'app') diff --git a/app/controllers/projects/prometheus/metrics_controller.rb b/app/controllers/projects/prometheus/metrics_controller.rb index 51b29855bcf..1dd886409a5 100644 --- a/app/controllers/projects/prometheus/metrics_controller.rb +++ b/app/controllers/projects/prometheus/metrics_controller.rb @@ -24,7 +24,6 @@ module Projects @prometheus_adapter ||= ::Prometheus::AdapterService.new(project).prometheus_adapter end - def require_prometheus_metrics! render_404 unless prometheus_adapter.can_query? end -- cgit v1.2.1 From 9cb7e93f09b1ff0c1c889a004479a8ef21abbae2 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Sat, 3 Mar 2018 05:59:40 -0800 Subject: Fix project dashboard showing the wrong timestamps Use the max of the `last_activity_at` and `last_repository_updated_at` columns. The latter is updated only when a push happens, but the former is updated whenever any activity (e.g. issue creation) happens. Closes #27181 --- app/models/project.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'app') diff --git a/app/models/project.rb b/app/models/project.rb index 5b1f8b2658b..099eaa53d23 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -274,7 +274,8 @@ class Project < ActiveRecord::Base scope :without_storage_feature, ->(feature) { where('storage_version < :version OR storage_version IS NULL', version: HASHED_STORAGE_FEATURES[feature]) } scope :with_unmigrated_storage, -> { where('storage_version < :version OR storage_version IS NULL', version: LATEST_STORAGE_VERSION) } - scope :sorted_by_activity, -> { reorder(last_activity_at: :desc) } + # last_activity_at is throttled every minute, but last_repository_updated_at is updated with every push + scope :sorted_by_activity, -> { reorder("GREATEST(COALESCE(last_activity_at, '1970-01-01'), COALESCE(last_repository_updated_at, '1970-01-01')) DESC") } scope :sorted_by_stars, -> { reorder('projects.star_count DESC') } scope :in_namespace, ->(namespace_ids) { where(namespace_id: namespace_ids) } @@ -776,7 +777,7 @@ class Project < ActiveRecord::Base end def last_activity_date - last_repository_updated_at || last_activity_at || updated_at + [last_activity_at, last_repository_updated_at, updated_at].compact.max end def project_id -- cgit v1.2.1 From 1c931f0784fc15601101fe356585812c93ac1587 Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Mon, 5 Mar 2018 21:57:48 +0900 Subject: Rework to minimize changes --- app/services/projects/update_pages_service.rb | 23 +++++++++++++++-------- app/workers/pages_worker.rb | 2 +- 2 files changed, 16 insertions(+), 9 deletions(-) (limited to 'app') diff --git a/app/services/projects/update_pages_service.rb b/app/services/projects/update_pages_service.rb index c760bd3b626..d3e792b9232 100644 --- a/app/services/projects/update_pages_service.rb +++ b/app/services/projects/update_pages_service.rb @@ -1,5 +1,6 @@ module Projects class UpdatePagesService < BaseService + InvaildStateError = Class.new(StandardError) BLOCK_SIZE = 32.kilobytes MAX_SIZE = 1.terabyte SITE_PATH = 'public/'.freeze @@ -11,13 +12,15 @@ module Projects end def execute + register_attempt + # Create status notifying the deployment of pages @status = create_status @status.enqueue! @status.run! - raise 'missing pages artifacts' unless build.artifacts? - raise 'pages are outdated' unless latest? + raise InvaildStateError, 'missing pages artifacts' unless build.artifacts? + raise InvaildStateError, 'pages are outdated' unless latest? # Create temporary directory in which we will extract the artifacts FileUtils.mkdir_p(tmp_path) @@ -26,24 +29,22 @@ module Projects # Check if we did extract public directory archive_public_path = File.join(archive_path, 'public') - raise 'pages miss the public folder' unless Dir.exist?(archive_public_path) - raise 'pages are outdated' unless latest? + raise InvaildStateError, 'pages miss the public folder' unless Dir.exist?(archive_public_path) + raise InvaildStateError, 'pages are outdated' unless latest? deploy_page!(archive_public_path) success end - rescue => e + rescue InvaildStateError => e register_failure error(e.message) - ensure - register_attempt - build.erase_artifacts! unless build.has_expiring_artifacts? end private def success @status.success + delete_artifact! super end @@ -52,6 +53,7 @@ module Projects @status.allow_failure = !latest? @status.description = message @status.drop(:script_failure) + delete_artifact! super end @@ -163,6 +165,11 @@ module Projects build.artifacts_file.path end + def delete_artifact! + build.reload + build.erase_artifacts! unless build.has_expiring_artifacts? + end + def latest_sha project.commit(build.ref).try(:sha).to_s end diff --git a/app/workers/pages_worker.rb b/app/workers/pages_worker.rb index d3b95009364..66a0ff83bef 100644 --- a/app/workers/pages_worker.rb +++ b/app/workers/pages_worker.rb @@ -1,7 +1,7 @@ class PagesWorker include ApplicationWorker - sidekiq_options retry: false + sidekiq_options retry: 3 def perform(action, *arg) send(action, *arg) # rubocop:disable GitlabSecurity/PublicSend -- cgit v1.2.1 From bbbf8e6a0234f1195a69facabab840679fb70dde Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Mon, 5 Mar 2018 21:59:16 +0900 Subject: Fix comment --- app/services/projects/update_pages_service.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app') diff --git a/app/services/projects/update_pages_service.rb b/app/services/projects/update_pages_service.rb index d3e792b9232..016660d5a72 100644 --- a/app/services/projects/update_pages_service.rb +++ b/app/services/projects/update_pages_service.rb @@ -166,7 +166,7 @@ module Projects end def delete_artifact! - build.reload + build.reload # Reload stable object to prevent erase artifacts with old state build.erase_artifacts! unless build.has_expiring_artifacts? end -- cgit v1.2.1 From 259a85e6658d91a7eb17b752b3f54c023625e08d Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Mon, 5 Mar 2018 22:02:50 +0900 Subject: Drop running_or_pending_build_count --- app/models/ci/build.rb | 1 - app/models/project.rb | 6 ------ 2 files changed, 7 deletions(-) (limited to 'app') diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index b230b7f47ef..3f037822154 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -359,7 +359,6 @@ module Ci project.execute_hooks(build_data.dup, :job_hooks) project.execute_services(build_data.dup, :job_hooks) PagesService.new(build_data).execute - project.running_or_pending_build_count(force: true) end def artifacts_metadata_entry(path, **options) diff --git a/app/models/project.rb b/app/models/project.rb index a11b1e4f554..58c4094918c 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1494,12 +1494,6 @@ class Project < ActiveRecord::Base update_column(:import_jid, nil) end - def running_or_pending_build_count(force: false) - Rails.cache.fetch(['projects', id, 'running_or_pending_build_count'], force: force) do - builds.running_or_pending.count(:all) - end - end - # Lazy loading of the `pipeline_status` attribute def pipeline_status @pipeline_status ||= Gitlab::Cache::Ci::ProjectPipelineStatus.load_for_project(self) -- cgit v1.2.1 From c8d1a04f30f858ff66cff6f9168b4a3fc6f88acf Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Tue, 6 Mar 2018 03:15:42 +0900 Subject: Add empty line after custom error difinition --- app/services/projects/update_pages_service.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'app') diff --git a/app/services/projects/update_pages_service.rb b/app/services/projects/update_pages_service.rb index 016660d5a72..cc50a23e8f7 100644 --- a/app/services/projects/update_pages_service.rb +++ b/app/services/projects/update_pages_service.rb @@ -1,6 +1,7 @@ module Projects class UpdatePagesService < BaseService InvaildStateError = Class.new(StandardError) + BLOCK_SIZE = 32.kilobytes MAX_SIZE = 1.terabyte SITE_PATH = 'public/'.freeze -- cgit v1.2.1 From 7421604bd0855f7855f5562769acc9bc871fb631 Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Tue, 6 Mar 2018 04:37:09 +0900 Subject: Introduce FailedToExtractError. Fix spec. Add DNS test mock. --- app/services/projects/update_pages_service.rb | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'app') diff --git a/app/services/projects/update_pages_service.rb b/app/services/projects/update_pages_service.rb index cc50a23e8f7..00fdd047208 100644 --- a/app/services/projects/update_pages_service.rb +++ b/app/services/projects/update_pages_service.rb @@ -1,6 +1,7 @@ module Projects class UpdatePagesService < BaseService InvaildStateError = Class.new(StandardError) + FailedToExtractError = Class.new(StandardError) BLOCK_SIZE = 32.kilobytes MAX_SIZE = 1.terabyte @@ -30,13 +31,13 @@ module Projects # Check if we did extract public directory archive_public_path = File.join(archive_path, 'public') - raise InvaildStateError, 'pages miss the public folder' unless Dir.exist?(archive_public_path) + raise FailedToExtractError, 'pages miss the public folder' unless Dir.exist?(archive_public_path) raise InvaildStateError, 'pages are outdated' unless latest? deploy_page!(archive_public_path) success end - rescue InvaildStateError => e + rescue InvaildStateError, FailedToExtractError => e register_failure error(e.message) end @@ -75,7 +76,7 @@ module Projects elsif artifacts.ends_with?('.zip') extract_zip_archive!(temp_path) else - raise 'unsupported artifacts format' + raise FailedToExtractError, 'unsupported artifacts format' end end @@ -84,17 +85,17 @@ module Projects %W(dd bs=#{BLOCK_SIZE} count=#{blocks}), %W(tar -x -C #{temp_path} #{SITE_PATH}), err: '/dev/null') - raise 'pages failed to extract' unless results.compact.all?(&:success?) + raise FailedToExtractError, 'pages failed to extract' unless results.compact.all?(&:success?) end def extract_zip_archive!(temp_path) - raise 'missing artifacts metadata' unless build.artifacts_metadata? + raise FailedToExtractError, 'missing artifacts metadata' unless build.artifacts_metadata? # Calculate page size after extract public_entry = build.artifacts_metadata_entry(SITE_PATH, recursive: true) if public_entry.total_size > max_size - raise "artifacts for pages are too large: #{public_entry.total_size}" + raise FailedToExtractError, "artifacts for pages are too large: #{public_entry.total_size}" end # Requires UnZip at least 6.00 Info-ZIP. @@ -103,7 +104,7 @@ module Projects # We add * to end of SITE_PATH, because we want to extract SITE_PATH and all subdirectories site_path = File.join(SITE_PATH, '*') unless system(*%W(unzip -qq -n #{artifacts} #{site_path} -d #{temp_path})) - raise 'pages failed to extract' + raise FailedToExtractError, 'pages failed to extract' end end -- cgit v1.2.1 From e9fad3e501f6c8fa7ebc58011e5bf9fff379617e Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Fri, 2 Mar 2018 05:50:17 -0800 Subject: Make --prune a configurable parameter in fetching a git remote By default, --prune is added to the command-line of a `git fetch` operation, but for repositories with many references this can take a long time to run. We shouldn't need to run --prune the first time we fetch a new repository. --- app/models/repository.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'app') diff --git a/app/models/repository.rb b/app/models/repository.rb index 1a14afb951a..e6b88320110 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -866,20 +866,20 @@ class Repository raw_repository.ancestor?(ancestor_id, descendant_id) end - def fetch_as_mirror(url, forced: false, refmap: :all_refs, remote_name: nil) + def fetch_as_mirror(url, forced: false, refmap: :all_refs, remote_name: nil, prune: true) unless remote_name remote_name = "tmp-#{SecureRandom.hex}" tmp_remote_name = true end add_remote(remote_name, url, mirror_refmap: refmap) - fetch_remote(remote_name, forced: forced) + fetch_remote(remote_name, forced: forced, prune: prune) ensure remove_remote(remote_name) if tmp_remote_name end - def fetch_remote(remote, forced: false, ssh_auth: nil, no_tags: false) - gitlab_shell.fetch_remote(raw_repository, remote, ssh_auth: ssh_auth, forced: forced, no_tags: no_tags) + def fetch_remote(remote, forced: false, ssh_auth: nil, no_tags: false, prune: true) + gitlab_shell.fetch_remote(raw_repository, remote, ssh_auth: ssh_auth, forced: forced, no_tags: no_tags, prune: prune) end def fetch_source_branch!(source_repository, source_branch, local_ref) -- cgit v1.2.1 From 50106474e8ebd4272be67a8eee5a6332c94f1d9d Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Wed, 21 Feb 2018 16:41:28 -0600 Subject: add prometheus cluster health monitoring empty state --- app/assets/javascripts/clusters/components/applications.vue | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'app') diff --git a/app/assets/javascripts/clusters/components/applications.vue b/app/assets/javascripts/clusters/components/applications.vue index 1325a268214..27136c7289f 100644 --- a/app/assets/javascripts/clusters/components/applications.vue +++ b/app/assets/javascripts/clusters/components/applications.vue @@ -117,7 +117,10 @@ -- cgit v1.2.1 From ab9ad2db4fbc40a81bb927de10a10aa7f32bba2a Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Thu, 22 Feb 2018 01:57:18 -0600 Subject: fix spacing around axis label text in small breakpoints --- app/assets/javascripts/monitoring/components/graph/legend.vue | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'app') diff --git a/app/assets/javascripts/monitoring/components/graph/legend.vue b/app/assets/javascripts/monitoring/components/graph/legend.vue index bdd00a61d85..3149397b61f 100644 --- a/app/assets/javascripts/monitoring/components/graph/legend.vue +++ b/app/assets/javascripts/monitoring/components/graph/legend.vue @@ -62,8 +62,9 @@ }, rectTransform() { - const yCoordinate = ((this.graphHeight - this.margin.top) / 2) - + (this.yLabelWidth / 2) + 10 || 0; + const yCoordinate = (((this.graphHeight - this.margin.top) + + this.measurements.axisLabelLineOffset) / 2) + + (this.yLabelWidth / 2) || 0; return `translate(0, ${yCoordinate}) rotate(-90)`; }, -- cgit v1.2.1 From 44b8348d58247897467603ea7adb5c83cdd937be Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Thu, 22 Feb 2018 01:57:50 -0600 Subject: add ability to override graph size measurements --- app/assets/javascripts/monitoring/components/dashboard.vue | 6 ++++++ app/assets/javascripts/monitoring/components/graph.vue | 7 ++++++- 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'app') diff --git a/app/assets/javascripts/monitoring/components/dashboard.vue b/app/assets/javascripts/monitoring/components/dashboard.vue index 3544dd96e3e..f1d61a1c360 100644 --- a/app/assets/javascripts/monitoring/components/dashboard.vue +++ b/app/assets/javascripts/monitoring/components/dashboard.vue @@ -26,6 +26,11 @@ required: false, default: true, }, + forceSmallGraph: { + type: Boolean, + required: false, + default: false, + }, documentationPath: { type: String, required: true, @@ -165,6 +170,7 @@ :project-path="projectPath" :tags-path="tagsPath" :show-legend="showLegend" + :small-graph="forceSmallGraph" />
diff --git a/app/assets/javascripts/monitoring/components/graph.vue b/app/assets/javascripts/monitoring/components/graph.vue index 30236d51d30..9e67a6f2146 100644 --- a/app/assets/javascripts/monitoring/components/graph.vue +++ b/app/assets/javascripts/monitoring/components/graph.vue @@ -57,6 +57,11 @@ required: false, default: true, }, + smallGraph: { + type: Boolean, + required: false, + default: false, + }, }, data() { @@ -135,7 +140,7 @@ const breakpointSize = bp.getBreakpointSize(); const query = this.graphData.queries[0]; this.margin = measurements.large.margin; - if (breakpointSize === 'xs' || breakpointSize === 'sm') { + if (this.smallGraph || breakpointSize === 'xs' || breakpointSize === 'sm') { this.graphHeight = 300; this.margin = measurements.small.margin; this.measurements = measurements.small; -- cgit v1.2.1 From 999ea368b7fe8dbec16bea7ff8fee3e7c6d93332 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Thu, 22 Feb 2018 02:06:35 -0600 Subject: lighten axis tick text --- app/assets/stylesheets/pages/environments.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'app') diff --git a/app/assets/stylesheets/pages/environments.scss b/app/assets/stylesheets/pages/environments.scss index 884665d35c7..58700661142 100644 --- a/app/assets/stylesheets/pages/environments.scss +++ b/app/assets/stylesheets/pages/environments.scss @@ -369,7 +369,8 @@ } > text { - font-size: 12px; + fill: $theme-gray-600; + font-size: 10px; } } -- cgit v1.2.1 From 283183d8881e41508c8d70c18e275e2890fe8ec3 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Thu, 22 Feb 2018 02:55:29 -0600 Subject: remove prometheus panel styling on cluster monitoring page --- .../javascripts/monitoring/components/dashboard.vue | 6 ++++++ .../javascripts/monitoring/components/graph_group.vue | 16 +++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) (limited to 'app') diff --git a/app/assets/javascripts/monitoring/components/dashboard.vue b/app/assets/javascripts/monitoring/components/dashboard.vue index f1d61a1c360..04374d2e1db 100644 --- a/app/assets/javascripts/monitoring/components/dashboard.vue +++ b/app/assets/javascripts/monitoring/components/dashboard.vue @@ -26,6 +26,11 @@ required: false, default: true, }, + showPanels: { + type: Boolean, + required: false, + default: true, + }, forceSmallGraph: { type: Boolean, required: false, @@ -159,6 +164,7 @@ v-for="(groupData, index) in store.groups" :key="index" :name="groupData.group" + :show-panels="showPanels" > -- cgit v1.2.1 From de382f5c01866cdeedff21048cbca4b3043a3057 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Tue, 6 Mar 2018 01:25:19 -0600 Subject: prefer getElementById --- app/assets/javascripts/monitoring/monitoring_bundle.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app') diff --git a/app/assets/javascripts/monitoring/monitoring_bundle.js b/app/assets/javascripts/monitoring/monitoring_bundle.js index a9b608e4433..f881a3954b9 100644 --- a/app/assets/javascripts/monitoring/monitoring_bundle.js +++ b/app/assets/javascripts/monitoring/monitoring_bundle.js @@ -2,7 +2,7 @@ import Vue from 'vue'; import Dashboard from './components/dashboard.vue'; export default () => { - const el = document.querySelector('#prometheus-graphs'); + const el = document.getElementById('prometheus-graphs'); if (el && el.dataset) { // eslint-disable-next-line no-new -- cgit v1.2.1 From 2859ddde48709afe32c66726ac811b8b717f3798 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Tue, 6 Mar 2018 03:38:42 -0600 Subject: coerce hasMetrics to a boolean value before instantiating the Vue component --- app/assets/javascripts/monitoring/components/dashboard.vue | 8 ++++---- app/assets/javascripts/monitoring/monitoring_bundle.js | 6 +++++- 2 files changed, 9 insertions(+), 5 deletions(-) (limited to 'app') diff --git a/app/assets/javascripts/monitoring/components/dashboard.vue b/app/assets/javascripts/monitoring/components/dashboard.vue index 04374d2e1db..8ca94ef3e2a 100644 --- a/app/assets/javascripts/monitoring/components/dashboard.vue +++ b/app/assets/javascripts/monitoring/components/dashboard.vue @@ -7,7 +7,6 @@ import EmptyState from './empty_state.vue'; import MonitoringStore from '../stores/monitoring_store'; import eventHub from '../event_hub'; - import { convertPermissionToBoolean } from '../../lib/utils/common_utils'; export default { components: { @@ -18,8 +17,9 @@ props: { hasMetrics: { - type: String, - required: true, + type: Boolean, + required: false, + default: true, }, showLegend: { type: Boolean, @@ -108,7 +108,7 @@ mounted() { this.resizeThrottled = _.throttle(this.resize, 600); - if (!convertPermissionToBoolean(this.hasMetrics)) { + if (!this.hasMetrics) { this.state = 'gettingStarted'; } else { this.getGraphsData(); diff --git a/app/assets/javascripts/monitoring/monitoring_bundle.js b/app/assets/javascripts/monitoring/monitoring_bundle.js index f881a3954b9..41270e015d4 100644 --- a/app/assets/javascripts/monitoring/monitoring_bundle.js +++ b/app/assets/javascripts/monitoring/monitoring_bundle.js @@ -1,4 +1,5 @@ import Vue from 'vue'; +import { convertPermissionToBoolean } from '~/lib/utils/common_utils'; import Dashboard from './components/dashboard.vue'; export default () => { @@ -10,7 +11,10 @@ export default () => { el, render(createElement) { return createElement(Dashboard, { - props: el.dataset, + props: { + ...el.dataset, + hasMetrics: convertPermissionToBoolean(el.dataset.hasMetrics), + }, }); }, }); -- cgit v1.2.1 From c428aaac6613b9fcfecd479f7bb510a6e74b761c Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Tue, 6 Mar 2018 20:33:42 +0900 Subject: Revert unnecessary code running_or_pending_build_count removal --- app/models/ci/build.rb | 1 + app/models/project.rb | 6 ++++++ 2 files changed, 7 insertions(+) (limited to 'app') diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 3f037822154..b230b7f47ef 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -359,6 +359,7 @@ module Ci project.execute_hooks(build_data.dup, :job_hooks) project.execute_services(build_data.dup, :job_hooks) PagesService.new(build_data).execute + project.running_or_pending_build_count(force: true) end def artifacts_metadata_entry(path, **options) diff --git a/app/models/project.rb b/app/models/project.rb index 58c4094918c..a11b1e4f554 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1494,6 +1494,12 @@ class Project < ActiveRecord::Base update_column(:import_jid, nil) end + def running_or_pending_build_count(force: false) + Rails.cache.fetch(['projects', id, 'running_or_pending_build_count'], force: force) do + builds.running_or_pending.count(:all) + end + end + # Lazy loading of the `pipeline_status` attribute def pipeline_status @pipeline_status ||= Gitlab::Cache::Ci::ProjectPipelineStatus.load_for_project(self) -- cgit v1.2.1 From 580d8953636266e40802fd8ea525c4908ebc8b9f Mon Sep 17 00:00:00 2001 From: Takuya Noguchi Date: Wed, 15 Nov 2017 23:56:36 +0900 Subject: Add overview of branches and a filter for active/stale branches --- app/controllers/projects/branches_controller.rb | 41 ++++++++++++++++--- app/finders/branches_finder.rb | 2 +- app/helpers/branches_helper.rb | 11 ----- app/views/projects/branches/_panel.html.haml | 19 +++++++++ app/views/projects/branches/index.html.haml | 53 +++++++++++++++++-------- 5 files changed, 92 insertions(+), 34 deletions(-) create mode 100644 app/views/projects/branches/_panel.html.haml (limited to 'app') diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb index cabafe26357..965cece600e 100644 --- a/app/controllers/projects/branches_controller.rb +++ b/app/controllers/projects/branches_controller.rb @@ -7,13 +7,19 @@ class Projects::BranchesController < Projects::ApplicationController before_action :authorize_download_code! before_action :authorize_push_code!, only: [:new, :create, :destroy, :destroy_all_merged] - def index - @sort = params[:sort].presence || sort_value_recently_updated - @branches = BranchesFinder.new(@repository, params.merge(sort: @sort)).execute - @branches = Kaminari.paginate_array(@branches).page(params[:page]) + # Support legacy URLs + before_action :redirect_for_legacy_index_sort_or_search, only: [:index] + def index respond_to do |format| format.html do + @sort = params[:sort].presence || sort_value_recently_updated + @mode = params[:state].presence || 'overview' + @overview_max_branches = 5 + + # Fetch branches for the specified mode + fetch_branches_by_mode + @refs_pipelines = @project.pipelines.latest_successful_for_refs(@branches.map(&:name)) @merged_branch_names = repository.merged_branch_names(@branches.map(&:name)) @@ -28,7 +34,9 @@ class Projects::BranchesController < Projects::ApplicationController end end format.json do - render json: @branches.map(&:name) + branches = BranchesFinder.new(@repository, params).execute + branches = Kaminari.paginate_array(branches).page(params[:page]) + render json: branches.map(&:name) end end end @@ -123,4 +131,27 @@ class Projects::BranchesController < Projects::ApplicationController context: 'autodeploy' ) end + + def redirect_for_legacy_index_sort_or_search + # Normalize a legacy URL with redirect + if request.format != :json && !params[:state].presence && [:sort, :search, :page].any? { |key| params[key].presence } + redirect_to project_branches_filtered_path(@project, state: 'all'), notice: 'Update your bookmarked URLs as filtered/sorted branches URL has been changed.' + end + end + + def fetch_branches_by_mode + if @mode == 'overview' + # overview mode + @active_branches, @stale_branches = BranchesFinder.new(@repository, sort: sort_value_recently_updated).execute.partition(&:active?) + # Here we get one more branch to indicate if there are more data we're not showing + @active_branches = @active_branches.first(@overview_max_branches + 1) + @stale_branches = @stale_branches.first(@overview_max_branches + 1) + @branches = @active_branches + @stale_branches + else + # active/stale/all view mode + @branches = BranchesFinder.new(@repository, params.merge(sort: @sort)).execute + @branches = @branches.select { |b| b.state.to_s == @mode } if %w[active stale].include?(@mode) + @branches = Kaminari.paginate_array(@branches).page(params[:page]) + end + end end diff --git a/app/finders/branches_finder.rb b/app/finders/branches_finder.rb index 852eac3647d..8bb1366867c 100644 --- a/app/finders/branches_finder.rb +++ b/app/finders/branches_finder.rb @@ -1,5 +1,5 @@ class BranchesFinder - def initialize(repository, params) + def initialize(repository, params = {}) @repository = repository @params = params end diff --git a/app/helpers/branches_helper.rb b/app/helpers/branches_helper.rb index 00b9a0e00eb..07b1fc3d7cf 100644 --- a/app/helpers/branches_helper.rb +++ b/app/helpers/branches_helper.rb @@ -1,15 +1,4 @@ module BranchesHelper - def filter_branches_path(options = {}) - exist_opts = { - search: params[:search], - sort: params[:sort] - } - - options = exist_opts.merge(options) - - project_branches_path(@project, @id, options) - end - def project_branches options_for_select(@project.repository.branch_names, @project.default_branch) end diff --git a/app/views/projects/branches/_panel.html.haml b/app/views/projects/branches/_panel.html.haml new file mode 100644 index 00000000000..12e5a8e8d69 --- /dev/null +++ b/app/views/projects/branches/_panel.html.haml @@ -0,0 +1,19 @@ +- branches = local_assigns.fetch(:branches) +- state = local_assigns.fetch(:state) +- panel_title = local_assigns.fetch(:panel_title) +- show_more_text = local_assigns.fetch(:show_more_text) +- project = local_assigns.fetch(:project) +- overview_max_branches = local_assigns.fetch(:overview_max_branches) + +- return unless branches.any? + +.panel.panel-default.prepend-top-10 + .panel-heading + %h4.panel-title + = panel_title + %ul.content-list.all-branches + - branches.first(overview_max_branches).each do |branch| + = render "projects/branches/branch", branch: branch, merged: project.repository.merged_to_root_ref?(branch) + - if branches.size > overview_max_branches + .panel-footer.text-center + = link_to show_more_text, project_branches_filtered_path(project, state: state), id: "state-#{state}", data: { state: state } diff --git a/app/views/projects/branches/index.html.haml b/app/views/projects/branches/index.html.haml index fb770764364..5dcc72d8263 100644 --- a/app/views/projects/branches/index.html.haml +++ b/app/views/projects/branches/index.html.haml @@ -3,26 +3,35 @@ %div{ class: container_class } .top-area.adjust - - if can?(current_user, :admin_project, @project) - .nav-text - - project_settings_link = link_to s_('Branches|project settings'), project_protected_branches_path(@project) - = s_('Branches|Protected branches can be managed in %{project_settings_link}').html_safe % { project_settings_link: project_settings_link } + %ul.nav-links.issues-state-filters + %li{ class: active_when(@mode == 'overview') }> + = link_to s_('Branches|Overview'), project_branches_path(@project), title: s_('Branches|Show overview of the branches') + + %li{ class: active_when(@mode == 'active') }> + = link_to s_('Branches|Active'), project_branches_filtered_path(@project, state: 'active'), title: s_('Branches|Show active branches') + + %li{ class: active_when(@mode == 'stale') }> + = link_to s_('Branches|Stale'), project_branches_filtered_path(@project, state: 'stale'), title: s_('Branches|Show stale branches') + + %li{ class: active_when(!%w[overview active stale].include?(@mode)) }> + = link_to s_('Branches|All'), project_branches_filtered_path(@project, state: 'all'), title: s_('Branches|Show all branches') .nav-controls - = form_tag(filter_branches_path, method: :get) do + = form_tag(project_branches_filtered_path(@project, state: 'all'), method: :get) do = search_field_tag :search, params[:search], { placeholder: s_('Branches|Filter by branch name'), id: 'branch-search', class: 'form-control search-text-input input-short', spellcheck: false } - .dropdown.inline> - %button.dropdown-menu-toggle{ type: 'button', 'data-toggle' => 'dropdown' } - %span.light - = branches_sort_options_hash[@sort] - = icon('chevron-down') - %ul.dropdown-menu.dropdown-menu-align-right.dropdown-menu-selectable - %li.dropdown-header - = s_('Branches|Sort by') - - branches_sort_options_hash.each do |value, title| - %li - = link_to title, filter_branches_path(sort: value), class: ("is-active" if @sort == value) + - unless @mode == 'overview' + .dropdown.inline> + %button.dropdown-menu-toggle{ type: 'button', 'data-toggle' => 'dropdown' } + %span.light + = branches_sort_options_hash[@sort] + = icon('chevron-down') + %ul.dropdown-menu.dropdown-menu-align-right.dropdown-menu-selectable + %li.dropdown-header + = s_('Branches|Sort by') + - branches_sort_options_hash.each do |value, title| + %li + = link_to title, project_branches_filtered_path(@project, state: 'all', search: params[:search], sort: value), class: ("is-active" if @sort == value) - if can? current_user, :push_code, @project = link_to project_merged_branches_path(@project), @@ -35,7 +44,17 @@ = link_to new_project_branch_path(@project), class: 'btn btn-create' do = s_('Branches|New branch') - - if @branches.any? + - if can?(current_user, :admin_project, @project) + - project_settings_link = link_to s_('Branches|project settings'), project_protected_branches_path(@project) + .row-content-block + %h5 + = s_('Branches|Protected branches can be managed in %{project_settings_link}.').html_safe % { project_settings_link: project_settings_link } + + - if @mode == 'overview' && (@active_branches.any? || @stale_branches.any?) + = render "projects/branches/panel", branches: @active_branches, state: 'active', panel_title: s_('Branches|Active branches'), show_more_text: s_('Branches|Show more active branches'), project: @project, overview_max_branches: @overview_max_branches + = render "projects/branches/panel", branches: @stale_branches, state: 'stale', panel_title: s_('Branches|Stale branches'), show_more_text: s_('Branches|Show more stale branches'), project: @project, overview_max_branches: @overview_max_branches + + - elsif @branches.any? %ul.content-list.all-branches - @branches.each do |branch| = render "projects/branches/branch", branch: branch, merged: @merged_branch_names.include?(branch.name) -- cgit v1.2.1 From f0d7a2ffc419e5e4893f9161c008d4ead5d3a660 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Trzci=C5=84ski?= Date: Fri, 23 Feb 2018 13:08:38 +0100 Subject: Proper fix for artifacts trace migration which is fully safe --- app/workers/create_trace_artifact_worker.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'app') diff --git a/app/workers/create_trace_artifact_worker.rb b/app/workers/create_trace_artifact_worker.rb index 11cda58021e..3283e8d79f0 100644 --- a/app/workers/create_trace_artifact_worker.rb +++ b/app/workers/create_trace_artifact_worker.rb @@ -2,9 +2,11 @@ class CreateTraceArtifactWorker include ApplicationWorker include PipelineQueue + # TODO: this worker should use BackgroundMigration or ObjectStorage queue + def perform(job_id) Ci::Build.preload(:project, :user).find_by(id: job_id).try do |job| - Ci::CreateTraceArtifactService.new(job.project, job.user).execute(job) + job.trace.archive! end end end -- cgit v1.2.1 From 32c1501d69d1618452e0088b343a6806769d79a9 Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Mon, 26 Feb 2018 23:06:04 +0900 Subject: Add rake task. Adopt the latest fix. Drop CreateTraceArtifactService --- app/services/ci/create_trace_artifact_service.rb | 36 ------------------------ app/workers/archive_legacy_trace_worker.rb | 10 +++++++ app/workers/create_trace_artifact_worker.rb | 4 +-- 3 files changed, 11 insertions(+), 39 deletions(-) delete mode 100644 app/services/ci/create_trace_artifact_service.rb create mode 100644 app/workers/archive_legacy_trace_worker.rb (limited to 'app') diff --git a/app/services/ci/create_trace_artifact_service.rb b/app/services/ci/create_trace_artifact_service.rb deleted file mode 100644 index ffde824972c..00000000000 --- a/app/services/ci/create_trace_artifact_service.rb +++ /dev/null @@ -1,36 +0,0 @@ -module Ci - class CreateTraceArtifactService < BaseService - def execute(job) - return if job.job_artifacts_trace - - job.trace.read do |stream| - break unless stream.file? - - clone_file!(stream.path, JobArtifactUploader.workhorse_upload_path) do |clone_path| - create_job_trace!(job, clone_path) - FileUtils.rm(stream.path) - end - end - end - - private - - def create_job_trace!(job, path) - File.open(path) do |stream| - job.create_job_artifacts_trace!( - project: job.project, - file_type: :trace, - file: stream) - end - end - - def clone_file!(src_path, temp_dir) - FileUtils.mkdir_p(temp_dir) - Dir.mktmpdir('tmp-trace', temp_dir) do |dir_path| - temp_path = File.join(dir_path, "job.log") - FileUtils.copy(src_path, temp_path) - yield(temp_path) - end - end - end -end diff --git a/app/workers/archive_legacy_trace_worker.rb b/app/workers/archive_legacy_trace_worker.rb new file mode 100644 index 00000000000..01b6224494b --- /dev/null +++ b/app/workers/archive_legacy_trace_worker.rb @@ -0,0 +1,10 @@ +class ArchiveLegacyTraceWorker + include ApplicationWorker + include ObjectStorageQueue + + def perform(job_id) + Ci::Build.find_by(id: job_id).try do |job| + job.trace.archive! + end + end +end diff --git a/app/workers/create_trace_artifact_worker.rb b/app/workers/create_trace_artifact_worker.rb index 3283e8d79f0..a0cec43157e 100644 --- a/app/workers/create_trace_artifact_worker.rb +++ b/app/workers/create_trace_artifact_worker.rb @@ -2,10 +2,8 @@ class CreateTraceArtifactWorker include ApplicationWorker include PipelineQueue - # TODO: this worker should use BackgroundMigration or ObjectStorage queue - def perform(job_id) - Ci::Build.preload(:project, :user).find_by(id: job_id).try do |job| + Ci::Build.find_by(id: job_id).try do |job| job.trace.archive! end end -- cgit v1.2.1 From cd3931876590448108ba54fa89274941ff8a97fe Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Wed, 28 Feb 2018 01:24:01 +0900 Subject: Add object_storage queue --- app/workers/all_queues.yml | 2 ++ 1 file changed, 2 insertions(+) (limited to 'app') diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml index 328db19be29..d8fa2a0eddb 100644 --- a/app/workers/all_queues.yml +++ b/app/workers/all_queues.yml @@ -104,3 +104,5 @@ - update_user_activity - upload_checksum - web_hook + +- object_storage:archive_legacy_trace_worker \ No newline at end of file -- cgit v1.2.1 From d4c9c5225118eedb731045f7d387cb0c192067f4 Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Thu, 1 Mar 2018 17:49:37 +0900 Subject: Add object_storage queue to sidekiq_queues.ym. and correct queue name in all_queues.yml. --- app/workers/all_queues.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app') diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml index d8fa2a0eddb..1d669556201 100644 --- a/app/workers/all_queues.yml +++ b/app/workers/all_queues.yml @@ -105,4 +105,4 @@ - upload_checksum - web_hook -- object_storage:archive_legacy_trace_worker \ No newline at end of file +- object_storage:archive_legacy_trace \ No newline at end of file -- cgit v1.2.1 From 481d0bc3db1c83fe50d6e1441d0d13aa227a757b Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Thu, 1 Mar 2018 18:01:55 +0900 Subject: Change the place of definition of object_storage:archive_legacy_trace --- app/workers/all_queues.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'app') diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml index 1d669556201..160a6a92dcb 100644 --- a/app/workers/all_queues.yml +++ b/app/workers/all_queues.yml @@ -62,6 +62,8 @@ - repository_check:repository_check_clear - repository_check:repository_check_single_repository +- object_storage:archive_legacy_trace + - default - mailers # ActionMailer::DeliveryJob.queue_name @@ -104,5 +106,3 @@ - update_user_activity - upload_checksum - web_hook - -- object_storage:archive_legacy_trace \ No newline at end of file -- cgit v1.2.1 From 335bc0fec05d282e2e4daa0e4a1bcb82ddec0594 Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Tue, 6 Mar 2018 20:20:36 +0900 Subject: Integrate two workers into one ArchiveTraceWorker with pipeline_background queue. This queue takes loqer precedence than pipeline_default. --- app/workers/all_queues.yml | 4 +--- app/workers/archive_legacy_trace_worker.rb | 10 ---------- app/workers/archive_trace_worker.rb | 10 ++++++++++ app/workers/build_finished_worker.rb | 2 +- app/workers/concerns/pipeline_background_queue.rb | 10 ++++++++++ app/workers/create_trace_artifact_worker.rb | 10 ---------- 6 files changed, 22 insertions(+), 24 deletions(-) delete mode 100644 app/workers/archive_legacy_trace_worker.rb create mode 100644 app/workers/archive_trace_worker.rb create mode 100644 app/workers/concerns/pipeline_background_queue.rb delete mode 100644 app/workers/create_trace_artifact_worker.rb (limited to 'app') diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml index 160a6a92dcb..9962eaccade 100644 --- a/app/workers/all_queues.yml +++ b/app/workers/all_queues.yml @@ -43,9 +43,9 @@ - pipeline_cache:expire_pipeline_cache - pipeline_creation:create_pipeline - pipeline_creation:run_pipeline_schedule +- pipeline_background:archive_trace - pipeline_default:build_coverage - pipeline_default:build_trace_sections -- pipeline_default:create_trace_artifact - pipeline_default:pipeline_metrics - pipeline_default:pipeline_notification - pipeline_default:update_head_pipeline_for_merge_request @@ -62,8 +62,6 @@ - repository_check:repository_check_clear - repository_check:repository_check_single_repository -- object_storage:archive_legacy_trace - - default - mailers # ActionMailer::DeliveryJob.queue_name diff --git a/app/workers/archive_legacy_trace_worker.rb b/app/workers/archive_legacy_trace_worker.rb deleted file mode 100644 index 01b6224494b..00000000000 --- a/app/workers/archive_legacy_trace_worker.rb +++ /dev/null @@ -1,10 +0,0 @@ -class ArchiveLegacyTraceWorker - include ApplicationWorker - include ObjectStorageQueue - - def perform(job_id) - Ci::Build.find_by(id: job_id).try do |job| - job.trace.archive! - end - end -end diff --git a/app/workers/archive_trace_worker.rb b/app/workers/archive_trace_worker.rb new file mode 100644 index 00000000000..dea7425ad88 --- /dev/null +++ b/app/workers/archive_trace_worker.rb @@ -0,0 +1,10 @@ +class ArchiveTraceWorker + include ApplicationWorker + include PipelineBackgroundQueue + + def perform(job_id) + Ci::Build.find_by(id: job_id).try do |job| + job.trace.archive! + end + end +end diff --git a/app/workers/build_finished_worker.rb b/app/workers/build_finished_worker.rb index b5ed8d607b3..46f1ac09915 100644 --- a/app/workers/build_finished_worker.rb +++ b/app/workers/build_finished_worker.rb @@ -12,7 +12,7 @@ class BuildFinishedWorker # We execute that async as this are two indepentent operations that can be executed after TraceSections and Coverage BuildHooksWorker.perform_async(build.id) - CreateTraceArtifactWorker.perform_async(build.id) + ArchiveTraceWorker.perform_async(build.id) end end end diff --git a/app/workers/concerns/pipeline_background_queue.rb b/app/workers/concerns/pipeline_background_queue.rb new file mode 100644 index 00000000000..8bf43de6b26 --- /dev/null +++ b/app/workers/concerns/pipeline_background_queue.rb @@ -0,0 +1,10 @@ +## +# Concern for setting Sidekiq settings for the low priority CI pipeline workers. +# +module PipelineBackgroundQueue + extend ActiveSupport::Concern + + included do + queue_namespace :pipeline_background + end +end diff --git a/app/workers/create_trace_artifact_worker.rb b/app/workers/create_trace_artifact_worker.rb deleted file mode 100644 index a0cec43157e..00000000000 --- a/app/workers/create_trace_artifact_worker.rb +++ /dev/null @@ -1,10 +0,0 @@ -class CreateTraceArtifactWorker - include ApplicationWorker - include PipelineQueue - - def perform(job_id) - Ci::Build.find_by(id: job_id).try do |job| - job.trace.archive! - end - end -end -- cgit v1.2.1 From b7bedd569be9ae55de0cf2bfbeadf3440c0b2c5d Mon Sep 17 00:00:00 2001 From: Kushal Pandya Date: Tue, 6 Mar 2018 18:45:38 +0530 Subject: Add `js-*` class to refer in JS --- .../javascripts/vue_shared/components/sidebar/labels_select/base.vue | 4 ++-- .../vue_shared/components/sidebar/labels_select/dropdown_value.vue | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'app') diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select/base.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select/base.vue index 3b17135f0e5..c1dd4d42d9d 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select/base.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select/base.vue @@ -88,7 +88,7 @@ export default {