summaryrefslogtreecommitdiff
path: root/app/models
diff options
context:
space:
mode:
authorShinya Maeda <shinya@gitlab.com>2018-05-22 14:32:40 +0900
committerShinya Maeda <shinya@gitlab.com>2018-05-22 14:32:40 +0900
commitf61666c0d70ed2d8457e4a8d8d23e68816498035 (patch)
tree67478ee365f1c1f652ed3f3e5e8c69eefe7a48ee /app/models
parent1c636b8080bad4f9ea8fb6992277e421816271ce (diff)
parentc6f72ac9a88521257991aa9a0cc6d558126f5bb9 (diff)
downloadgitlab-ce-f61666c0d70ed2d8457e4a8d8d23e68816498035.tar.gz
Merge branch 'master' into per-project-pipeline-iid
Diffstat (limited to 'app/models')
-rw-r--r--app/models/ci/build.rb5
-rw-r--r--app/models/ci/pipeline.rb20
-rw-r--r--app/models/ci/runner.rb2
-rw-r--r--app/models/clusters/applications/prometheus.rb5
-rw-r--r--app/models/commit.rb28
-rw-r--r--app/models/commit_status.rb1
-rw-r--r--app/models/concerns/redis_cacheable.rb19
-rw-r--r--app/models/concerns/sortable.rb4
-rw-r--r--app/models/concerns/time_trackable.rb4
-rw-r--r--app/models/project.rb10
-rw-r--r--app/models/user.rb10
11 files changed, 97 insertions, 11 deletions
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index 61c10c427dd..495430931aa 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -184,7 +184,7 @@ module Ci
end
def playable?
- action? && (manual? || complete?)
+ action? && (manual? || retryable?)
end
def action?
@@ -599,6 +599,7 @@ module Ci
break variables unless persisted?
variables
+ .concat(pipeline.persisted_variables)
.append(key: 'CI_JOB_ID', value: id.to_s)
.append(key: 'CI_JOB_TOKEN', value: token, public: false)
.append(key: 'CI_BUILD_ID', value: id.to_s)
@@ -661,7 +662,7 @@ module Ci
Gitlab::Ci::Variables::Collection.new.tap do |variables|
break variables unless gitlab_deploy_token
- variables.append(key: 'CI_DEPLOY_USER', value: gitlab_deploy_token.name)
+ variables.append(key: 'CI_DEPLOY_USER', value: gitlab_deploy_token.username)
variables.append(key: 'CI_DEPLOY_PASSWORD', value: gitlab_deploy_token.token, public: false)
end
end
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index b1412f2bcb2..5eb30f4aaa0 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -411,7 +411,18 @@ module Ci
end
def has_warnings?
- builds.latest.failed_but_allowed.any?
+ number_of_warnings.positive?
+ end
+
+ def number_of_warnings
+ BatchLoader.for(id).batch(default_value: 0) do |pipeline_ids, loader|
+ Build.where(commit_id: pipeline_ids)
+ .latest
+ .failed_but_allowed
+ .group(:commit_id)
+ .count
+ .each { |id, amount| loader.call(id, amount) }
+ end
end
def set_config_source
@@ -517,9 +528,14 @@ module Ci
strong_memoize(:legacy_trigger) { trigger_requests.first }
end
+ def persisted_variables
+ Gitlab::Ci::Variables::Collection.new.tap do |variables|
+ variables.append(key: 'CI_PIPELINE_ID', value: id.to_s) if persisted?
+ end
+ end
+
def predefined_variables
Gitlab::Ci::Variables::Collection.new
- .append(key: 'CI_PIPELINE_ID', value: id.to_s)
.append(key: 'CI_PIPELINE_IID', value: iid.to_s)
.append(key: 'CI_CONFIG_PATH', value: ci_yaml_file_path)
.append(key: 'CI_PIPELINE_SOURCE', value: source.to_s)
diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb
index e6f1ed519be..530eacf4be0 100644
--- a/app/models/ci/runner.rb
+++ b/app/models/ci/runner.rb
@@ -75,7 +75,7 @@ module Ci
project_type: 3
}
- cached_attr_reader :version, :revision, :platform, :architecture, :contacted_at, :ip_address
+ cached_attr_reader :version, :revision, :platform, :architecture, :ip_address, :contacted_at
chronic_duration_attr :maximum_timeout_human_readable, :maximum_timeout
diff --git a/app/models/clusters/applications/prometheus.rb b/app/models/clusters/applications/prometheus.rb
index 7b25d8c4089..c702c4ee807 100644
--- a/app/models/clusters/applications/prometheus.rb
+++ b/app/models/clusters/applications/prometheus.rb
@@ -49,6 +49,11 @@ module Clusters
# ensures headers containing auth data are appended to original k8s client options
options = kube_client.rest_client.options.merge(headers: kube_client.headers)
RestClient::Resource.new(proxy_url, options)
+ rescue Kubeclient::HttpError
+ # 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.
+ # Since `PrometheusAdapter#can_query?` is eargely loaded on environement pages in gitlab,
+ # we need to silence the exceptions
end
private
diff --git a/app/models/commit.rb b/app/models/commit.rb
index b46f9f34689..56d4c86774e 100644
--- a/app/models/commit.rb
+++ b/app/models/commit.rb
@@ -224,8 +224,34 @@ class Commit
Gitlab::ClosingIssueExtractor.new(project, current_user).closed_by_message(safe_message)
end
+ def lazy_author
+ BatchLoader.for(author_email.downcase).batch do |emails, loader|
+ # A Hash that maps user Emails to the corresponding User objects. The
+ # Emails at this point are the _primary_ Emails of the Users.
+ users_for_emails = User
+ .by_any_email(emails)
+ .each_with_object({}) { |user, hash| hash[user.email] = user }
+
+ users_for_ids = users_for_emails
+ .values
+ .each_with_object({}) { |user, hash| hash[user.id] = user }
+
+ # Some commits may have used an alternative Email address. In this case we
+ # need to query the "emails" table to map those addresses to User objects.
+ Email
+ .where(email: emails - users_for_emails.keys)
+ .pluck(:email, :user_id)
+ .each { |(email, id)| users_for_emails[email] = users_for_ids[id] }
+
+ users_for_emails.each { |email, user| loader.call(email, user) }
+ end
+ end
+
def author
- User.find_by_any_email(author_email.downcase)
+ # We use __sync so that we get the actual objects back (including an actual
+ # nil), instead of a wrapper, as returning a wrapped nil breaks a lot of
+ # code.
+ lazy_author.__sync
end
request_cache(:author) { author_email.downcase }
diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb
index 97d89422594..a7d05722287 100644
--- a/app/models/commit_status.rb
+++ b/app/models/commit_status.rb
@@ -2,6 +2,7 @@ class CommitStatus < ActiveRecord::Base
include HasStatus
include Importable
include AfterCommitQueue
+ include Presentable
self.table_name = 'ci_builds'
diff --git a/app/models/concerns/redis_cacheable.rb b/app/models/concerns/redis_cacheable.rb
index b889f4202dc..b5425295130 100644
--- a/app/models/concerns/redis_cacheable.rb
+++ b/app/models/concerns/redis_cacheable.rb
@@ -7,7 +7,11 @@ module RedisCacheable
class_methods do
def cached_attr_reader(*attributes)
attributes.each do |attribute|
- define_method("#{attribute}") do
+ define_method(attribute) do
+ unless self.has_attribute?(attribute)
+ raise ArgumentError, "`cached_attr_reader` requires the #{self.class.name}\##{attribute} attribute to have a database column"
+ end
+
cached_attribute(attribute) || read_attribute(attribute)
end
end
@@ -15,13 +19,16 @@ module RedisCacheable
end
def cached_attribute(attribute)
- (cached_attributes || {})[attribute]
+ cached_value = (cached_attributes || {})[attribute]
+ cast_value_from_cache(attribute, cached_value) if cached_value
end
def cache_attributes(values)
Gitlab::Redis::SharedState.with do |redis|
redis.set(cache_attribute_key, values.to_json, ex: CACHED_ATTRIBUTES_EXPIRY_TIME)
end
+
+ clear_memoization(:cached_attributes)
end
private
@@ -38,4 +45,12 @@ module RedisCacheable
end
end
end
+
+ def cast_value_from_cache(attribute, value)
+ if Gitlab.rails5?
+ self.class.type_for_attribute(attribute).cast(value)
+ else
+ self.class.column_for_attribute(attribute).type_cast_from_database(value)
+ end
+ end
end
diff --git a/app/models/concerns/sortable.rb b/app/models/concerns/sortable.rb
index cefa5c13c5f..db7254c27e0 100644
--- a/app/models/concerns/sortable.rb
+++ b/app/models/concerns/sortable.rb
@@ -12,8 +12,8 @@ module Sortable
scope :order_created_asc, -> { reorder(created_at: :asc) }
scope :order_updated_desc, -> { reorder(updated_at: :desc) }
scope :order_updated_asc, -> { reorder(updated_at: :asc) }
- scope :order_name_asc, -> { reorder(name: :asc) }
- scope :order_name_desc, -> { reorder(name: :desc) }
+ scope :order_name_asc, -> { reorder("lower(name) asc") }
+ scope :order_name_desc, -> { reorder("lower(name) desc") }
end
module ClassMethods
diff --git a/app/models/concerns/time_trackable.rb b/app/models/concerns/time_trackable.rb
index 73fc5048dcf..1caf47072bc 100644
--- a/app/models/concerns/time_trackable.rb
+++ b/app/models/concerns/time_trackable.rb
@@ -53,6 +53,10 @@ module TimeTrackable
Gitlab::TimeTrackingFormatter.output(time_estimate)
end
+ def time_estimate=(val)
+ val.is_a?(Integer) ? super([val, Gitlab::Database::MAX_INT_VALUE].min) : super(val)
+ end
+
private
def touchable?
diff --git a/app/models/project.rb b/app/models/project.rb
index 0975e64e995..35c873830a7 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -997,7 +997,7 @@ class Project < ActiveRecord::Base
available_services_names = Service.available_services_names - exceptions
- available_services_names.map do |service_name|
+ available_services = available_services_names.map do |service_name|
service = find_service(services, service_name)
if service
@@ -1014,6 +1014,14 @@ class Project < ActiveRecord::Base
end
end
end
+
+ available_services.reject do |service|
+ disabled_services.include?(service.to_param)
+ end
+ end
+
+ def disabled_services
+ []
end
def find_or_initialize_service(name)
diff --git a/app/models/user.rb b/app/models/user.rb
index 474fde36c02..8ef3c3ceff0 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -860,6 +860,16 @@ class User < ActiveRecord::Base
confirmed? && !temp_oauth_email?
end
+ def accept_pending_invitations!
+ pending_invitations.select do |member|
+ member.accept_invite!(self)
+ end
+ end
+
+ def pending_invitations
+ Member.where(invite_email: verified_emails).invite
+ end
+
def all_emails
all_emails = []
all_emails << email unless temp_oauth_email?