Commit f24c43da authored by GitLab Bot's avatar GitLab Bot
Browse files

Add latest changes from gitlab-org/gitlab@master

parent 038949853ce8
...@@ -5,9 +5,11 @@ import initNotes from '~/init_notes'; ...@@ -5,9 +5,11 @@ import initNotes from '~/init_notes';
import snippetEmbed from '~/snippet/snippet_embed'; import snippetEmbed from '~/snippet/snippet_embed';
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
new LineHighlighter(); // eslint-disable-line no-new if (!gon.features.snippetsVue) {
new BlobViewer(); // eslint-disable-line no-new new LineHighlighter(); // eslint-disable-line no-new
initNotes(); new BlobViewer(); // eslint-disable-line no-new
new ZenMode(); // eslint-disable-line no-new initNotes();
snippetEmbed(); new ZenMode(); // eslint-disable-line no-new
snippetEmbed();
}
}); });
# frozen_string_literal: true
module Clusters
class KnativeServingNamespaceFinder
attr_reader :cluster
def initialize(cluster)
@cluster = cluster
end
def execute
cluster.kubeclient&.get_namespace(Clusters::Kubernetes::KNATIVE_SERVING_NAMESPACE)
rescue Kubeclient::ResourceNotFoundError
nil
end
end
end
...@@ -9,9 +9,9 @@ def initialize(cluster) ...@@ -9,9 +9,9 @@ def initialize(cluster)
end end
def execute def execute
cluster&.kubeclient&.get_cluster_role_bindings&.find do |resource| cluster.kubeclient&.get_cluster_role_binding(Clusters::Kubernetes::GITLAB_KNATIVE_VERSION_ROLE_BINDING_NAME)
resource.metadata.name == Clusters::Kubernetes::GITLAB_KNATIVE_VERSION_ROLE_BINDING_NAME rescue Kubeclient::ResourceNotFoundError
end nil
end end
end end
end end
...@@ -22,9 +22,28 @@ def execute ...@@ -22,9 +22,28 @@ def execute
private private
# rubocop: disable CodeReuse/ActiveRecord
def init_collection def init_collection
project.deployments project
.deployments
.includes(
:user,
environment: [],
deployable: {
job_artifacts: [],
pipeline: {
project: {
route: [],
namespace: :route
}
},
project: {
namespace: :route
}
}
)
end end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
def sort(items) def sort(items)
...@@ -43,6 +62,9 @@ def sort_params ...@@ -43,6 +62,9 @@ def sort_params
order_by = ALLOWED_SORT_VALUES.include?(params[:order_by]) ? params[:order_by] : DEFAULT_SORT_VALUE order_by = ALLOWED_SORT_VALUES.include?(params[:order_by]) ? params[:order_by] : DEFAULT_SORT_VALUE
order_direction = ALLOWED_SORT_DIRECTIONS.include?(params[:sort]) ? params[:sort] : DEFAULT_SORT_DIRECTION order_direction = ALLOWED_SORT_DIRECTIONS.include?(params[:sort]) ? params[:sort] : DEFAULT_SORT_DIRECTION
{ order_by => order_direction } { order_by => order_direction }.tap do |sort_values|
sort_values['id'] = 'desc' if sort_values['updated_at']
sort_values['id'] = sort_values.delete('created_at') if sort_values['created_at'] # Sorting by `id` produces the same result as sorting by `created_at`
end
end end
end end
...@@ -84,13 +84,17 @@ def prometheus_client ...@@ -84,13 +84,17 @@ def prometheus_client
# ensures headers containing auth data are appended to original k8s client options # ensures headers containing auth data are appended to original k8s client options
options = kube_client.rest_client.options.merge(headers: kube_client.headers) options = kube_client.rest_client.options.merge(headers: kube_client.headers)
Gitlab::PrometheusClient.new(proxy_url, options) Gitlab::PrometheusClient.new(proxy_url, options)
rescue Kubeclient::HttpError rescue Kubeclient::HttpError, Errno::ECONNRESET, Errno::ECONNREFUSED
# If users have mistakenly set parameters or removed the depended clusters, # If users have mistakenly set parameters or removed the depended clusters,
# `proxy_url` could raise an exception because gitlab can not communicate with the cluster. # `proxy_url` could raise an exception because gitlab can not communicate with the cluster.
# Since `PrometheusAdapter#can_query?` is eargely loaded on environement pages in gitlab, # Since `PrometheusAdapter#can_query?` is eargely loaded on environement pages in gitlab,
# we need to silence the exceptions # we need to silence the exceptions
end end
def configured?
kube_client.present? && available?
end
private private
def disable_prometheus_integration def disable_prometheus_integration
......
...@@ -16,6 +16,14 @@ def prometheus_client ...@@ -16,6 +16,14 @@ def prometheus_client
raise NotImplementedError raise NotImplementedError
end end
# This is a light-weight check if a prometheus client is properly configured.
def configured?
raise NotImplemented
end
# This is a heavy-weight check if a prometheus is properly configured and accesible from GitLab.
# This actually sends a request to an external service and often it could take a long time,
# Please consider using `configured?` instead if the process is running on unicorn/puma threads.
def can_query? def can_query?
prometheus_client.present? prometheus_client.present?
end end
......
...@@ -193,11 +193,11 @@ def deployment_namespace ...@@ -193,11 +193,11 @@ def deployment_namespace
end end
def has_metrics? def has_metrics?
available? && prometheus_adapter&.can_query? available? && prometheus_adapter&.configured?
end end
def metrics def metrics
prometheus_adapter.query(:environment, self) if has_metrics? prometheus_adapter.query(:environment, self) if has_metrics? && prometheus_adapter.can_query?
end end
def prometheus_status def prometheus_status
......
...@@ -374,9 +374,17 @@ class Project < ApplicationRecord ...@@ -374,9 +374,17 @@ class Project < ApplicationRecord
scope :pending_delete, -> { where(pending_delete: true) } scope :pending_delete, -> { where(pending_delete: true) }
scope :without_deleted, -> { where(pending_delete: false) } scope :without_deleted, -> { where(pending_delete: false) }
scope :with_storage_feature, ->(feature) { where('storage_version >= :version', version: HASHED_STORAGE_FEATURES[feature]) } scope :with_storage_feature, ->(feature) do
scope :without_storage_feature, ->(feature) { where('storage_version < :version OR storage_version IS NULL', version: HASHED_STORAGE_FEATURES[feature]) } where(arel_table[:storage_version].gteq(HASHED_STORAGE_FEATURES[feature]))
scope :with_unmigrated_storage, -> { where('storage_version < :version OR storage_version IS NULL', version: LATEST_STORAGE_VERSION) } end
scope :without_storage_feature, ->(feature) do
where(arel_table[:storage_version].lt(HASHED_STORAGE_FEATURES[feature])
.or(arel_table[:storage_version].eq(nil)))
end
scope :with_unmigrated_storage, -> do
where(arel_table[:storage_version].lt(LATEST_STORAGE_VERSION)
.or(arel_table[:storage_version].eq(nil)))
end
# last_activity_at is throttled every minute, but last_repository_updated_at is updated with every push # last_activity_at is throttled every minute, but last_repository_updated_at is updated with every push
scope :sorted_by_activity, -> { reorder(Arel.sql("GREATEST(COALESCE(last_activity_at, '1970-01-01'), COALESCE(last_repository_updated_at, '1970-01-01')) DESC")) } scope :sorted_by_activity, -> { reorder(Arel.sql("GREATEST(COALESCE(last_activity_at, '1970-01-01'), COALESCE(last_repository_updated_at, '1970-01-01')) DESC")) }
......
...@@ -95,6 +95,10 @@ def allow_local_api_url? ...@@ -95,6 +95,10 @@ def allow_local_api_url?
self_monitoring_project? && internal_prometheus_url? self_monitoring_project? && internal_prometheus_url?
end end
def configured?
should_return_client?
end
private private
def self_monitoring_project? def self_monitoring_project?
......
...@@ -23,6 +23,21 @@ class Upload < ApplicationRecord ...@@ -23,6 +23,21 @@ class Upload < ApplicationRecord
after_destroy :delete_file!, if: -> { uploader_class <= FileUploader } after_destroy :delete_file!, if: -> { uploader_class <= FileUploader }
class << self class << self
def inner_join_local_uploads_projects
upload_table = Upload.arel_table
project_table = Project.arel_table
join_statement = upload_table.project(upload_table[Arel.star])
.join(project_table)
.on(
upload_table[:model_type].eq('Project')
.and(upload_table[:model_id].eq(project_table[:id]))
.and(upload_table[:store].eq(ObjectStorage::Store::LOCAL))
)
joins(join_statement.join_sources)
end
## ##
# FastDestroyAll concerns # FastDestroyAll concerns
def begin_fast_destroy def begin_fast_destroy
......
...@@ -71,9 +71,9 @@ def ensure_project_namespace_exists ...@@ -71,9 +71,9 @@ def ensure_project_namespace_exists
end end
def knative_serving_namespace def knative_serving_namespace
kubeclient.core_client.get_namespaces.find do |namespace| kubeclient.get_namespace(Clusters::Kubernetes::KNATIVE_SERVING_NAMESPACE)
namespace.metadata.name == Clusters::Kubernetes::KNATIVE_SERVING_NAMESPACE rescue Kubeclient::ResourceNotFoundError
end nil
end end
def create_role_or_cluster_role_binding def create_role_or_cluster_role_binding
......
...@@ -4,13 +4,16 @@ ...@@ -4,13 +4,16 @@
- breadcrumb_title @snippet.to_reference - breadcrumb_title @snippet.to_reference
- page_title "#{@snippet.title} (#{@snippet.to_reference})", _("Snippets") - page_title "#{@snippet.title} (#{@snippet.to_reference})", _("Snippets")
= render 'shared/snippets/header' - if Feature.enabled?(:snippets_vue)
#js-snippet-view{ 'data-qa-selector': 'snippet_view' }
- else
= render 'shared/snippets/header'
.personal-snippets .personal-snippets
%article.file-holder.snippet-file-content %article.file-holder.snippet-file-content
= render 'shared/snippets/blob' = render 'shared/snippets/blob'
.row-content-block.top-block.content-component-block .row-content-block.top-block.content-component-block
= render 'award_emoji/awards_block', awardable: @snippet, inline: true = render 'award_emoji/awards_block', awardable: @snippet, inline: true
#notes.limited-width-notes= render "shared/notes/notes_with_form", :autocomplete => false #notes.limited-width-notes= render "shared/notes/notes_with_form", :autocomplete => false
...@@ -14,7 +14,7 @@ def perform(project_id, old_disk_path = nil) ...@@ -14,7 +14,7 @@ def perform(project_id, old_disk_path = nil)
try_obtain_lease do try_obtain_lease do
project = Project.without_deleted.find_by(id: project_id) project = Project.without_deleted.find_by(id: project_id)
break unless project break unless project && project.storage_upgradable?
old_disk_path ||= Storage::LegacyProject.new(project).disk_path old_disk_path ||= Storage::LegacyProject.new(project).disk_path
......
---
title: Added lightweight check when retrieving Prometheus metrics.
merge_request: 21099
author:
type: performance
---
title: 'Hashed Storage attachments migration: exclude files in object storage as they
are all hashed already'
merge_request: 20338
author:
type: changed
---
title: Optimize Deployments endpoint by preloading associations and make record ordering more consistent
merge_request: 20848
author:
type: changed
# frozen_string_literal: true
class ChangeUpdatedAtIndexAndAddIndexToIdOnDeployments < ActiveRecord::Migration[5.2]
include Gitlab::Database::MigrationHelpers
disable_ddl_transaction!
DOWNTIME = false
PROJECT_ID_INDEX_PARAMS = [[:project_id, :id], order: { id: :desc }]
OLD_UPDATED_AT_INDEX_PARAMS = [[:project_id, :updated_at]]
NEW_UPDATED_AT_INDEX_PARAMS = [[:project_id, :updated_at, :id], order: { updated_at: :desc, id: :desc }]
def up
add_concurrent_index :deployments, *NEW_UPDATED_AT_INDEX_PARAMS
remove_concurrent_index :deployments, *OLD_UPDATED_AT_INDEX_PARAMS
add_concurrent_index :deployments, *PROJECT_ID_INDEX_PARAMS
end
def down
add_concurrent_index :deployments, *OLD_UPDATED_AT_INDEX_PARAMS
remove_concurrent_index :deployments, *NEW_UPDATED_AT_INDEX_PARAMS
remove_concurrent_index :deployments, *PROJECT_ID_INDEX_PARAMS
end
end
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2019_12_02_031812) do ActiveRecord::Schema.define(version: 2019_12_04_070713) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "pg_trgm" enable_extension "pg_trgm"
...@@ -1339,10 +1339,11 @@ ...@@ -1339,10 +1339,11 @@
t.index ["environment_id", "iid", "project_id"], name: "index_deployments_on_environment_id_and_iid_and_project_id" t.index ["environment_id", "iid", "project_id"], name: "index_deployments_on_environment_id_and_iid_and_project_id"
t.index ["environment_id", "status"], name: "index_deployments_on_environment_id_and_status" t.index ["environment_id", "status"], name: "index_deployments_on_environment_id_and_status"
t.index ["id"], name: "partial_index_deployments_for_legacy_successful_deployments", where: "((finished_at IS NULL) AND (status = 2))" t.index ["id"], name: "partial_index_deployments_for_legacy_successful_deployments", where: "((finished_at IS NULL) AND (status = 2))"
t.index ["project_id", "id"], name: "index_deployments_on_project_id_and_id", order: { id: :desc }
t.index ["project_id", "iid"], name: "index_deployments_on_project_id_and_iid", unique: true t.index ["project_id", "iid"], name: "index_deployments_on_project_id_and_iid", unique: true
t.index ["project_id", "status", "created_at"], name: "index_deployments_on_project_id_and_status_and_created_at" t.index ["project_id", "status", "created_at"], name: "index_deployments_on_project_id_and_status_and_created_at"
t.index ["project_id", "status"], name: "index_deployments_on_project_id_and_status" t.index ["project_id", "status"], name: "index_deployments_on_project_id_and_status"
t.index ["project_id", "updated_at"], name: "index_deployments_on_project_id_and_updated_at" t.index ["project_id", "updated_at", "id"], name: "index_deployments_on_project_id_and_updated_at_and_id", order: { updated_at: :desc, id: :desc }
end end
create_table "description_versions", force: :cascade do |t| create_table "description_versions", force: :cascade do |t|
......
...@@ -8,7 +8,7 @@ class KubernetesNamespace < Base ...@@ -8,7 +8,7 @@ class KubernetesNamespace < Base
def unmet? def unmet?
deployment_cluster.present? && deployment_cluster.present? &&
deployment_cluster.managed? && deployment_cluster.managed? &&
(missing_namespace? || missing_knative_version_role_binding?) (missing_namespace? || need_knative_version_role_binding?)
end end
def complete! def complete!
...@@ -23,8 +23,8 @@ def missing_namespace? ...@@ -23,8 +23,8 @@ def missing_namespace?
kubernetes_namespace.nil? || kubernetes_namespace.service_account_token.blank? kubernetes_namespace.nil? || kubernetes_namespace.service_account_token.blank?
end end
def missing_knative_version_role_binding? def need_knative_version_role_binding?
knative_version_role_binding.nil? !knative_serving_namespace.nil? && knative_version_role_binding.nil?
end end
def deployment_cluster def deployment_cluster
...@@ -35,6 +35,14 @@ def environment ...@@ -35,6 +35,14 @@ def environment
build.deployment.environment build.deployment.environment
end end
def knative_serving_namespace
strong_memoize(:knative_serving_namespace) do
Clusters::KnativeServingNamespaceFinder.new(
deployment_cluster
).execute
end
end
def knative_version_role_binding def knative_version_role_binding
strong_memoize(:knative_version_role_binding) do strong_memoize(:knative_version_role_binding) do
Clusters::KnativeVersionRoleBindingFinder.new( Clusters::KnativeVersionRoleBindingFinder.new(
......
...@@ -42,6 +42,7 @@ def add_gon_variables ...@@ -42,6 +42,7 @@ def add_gon_variables
# Initialize gon.features with any flags that should be # Initialize gon.features with any flags that should be
# made globally available to the frontend # made globally available to the frontend
push_frontend_feature_flag(:suppress_ajax_navigation_errors, default_enabled: true) push_frontend_feature_flag(:suppress_ajax_navigation_errors, default_enabled: true)
push_frontend_feature_flag(:snippets_vue, default_enabled: false)
end end
# Exposes the state of a feature flag to the frontend code. # Exposes the state of a feature flag to the frontend code.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment