diff options
author | Shinya Maeda <shinya@gitlab.com> | 2017-10-06 18:27:15 +0300 |
---|---|---|
committer | Shinya Maeda <shinya@gitlab.com> | 2017-10-06 18:27:15 +0300 |
commit | 830c770a532fc94e1b1a70064500c9bd63712de4 (patch) | |
tree | 140141b7c9ac92cdce29e71b6da6f00bcde9f51a /app | |
parent | 3e26b0dcd113ade77dc8304137c6733cab4c8718 (diff) | |
parent | 7f8e720f415ff50f791d9efd49b774c9da9ab109 (diff) |
Merge branch 'master' into feature/sm/35954-create-kubernetes-cluster-on-gke-from-k8s-service
Diffstat (limited to 'app')
18 files changed, 154 insertions, 19 deletions
diff --git a/app/assets/javascripts/cycle_analytics/components/total_time_component.vue b/app/assets/javascripts/cycle_analytics/components/total_time_component.vue index 9941b997b3f..62efd4f9c28 100644 --- a/app/assets/javascripts/cycle_analytics/components/total_time_component.vue +++ b/app/assets/javascripts/cycle_analytics/components/total_time_component.vue @@ -20,7 +20,7 @@ <template v-if="time.days">{{ time.days }} <span>{{ n__('day', 'days', time.days) }}</span></template> <template v-if="time.hours">{{ time.hours }} <span>{{ n__('Time|hr', 'Time|hrs', time.hours) }}</span></template> <template v-if="time.mins && !time.days">{{ time.mins }} <span>{{ n__('Time|min', 'Time|mins', time.mins) }}</span></template> - <template v-if="time.seconds && hasDa === 1 || time.seconds === 0">{{ time.seconds }} <span>{{ s__('Time|s') }}</span></template> + <template v-if="time.seconds && hasData === 1 || time.seconds === 0">{{ time.seconds }} <span>{{ s__('Time|s') }}</span></template> </template> <template v-else> -- diff --git a/app/assets/javascripts/locale/index.js b/app/assets/javascripts/locale/index.js index ce05b3eabec..1003b9ba0af 100644 --- a/app/assets/javascripts/locale/index.js +++ b/app/assets/javascripts/locale/index.js @@ -4,6 +4,7 @@ import sprintf from './sprintf'; const langAttribute = document.querySelector('html').getAttribute('lang'); const lang = (langAttribute || 'en').replace(/-/g, '_'); const locale = new Jed(window.translations || {}); +delete window.translations; /** Translates `text` diff --git a/app/assets/javascripts/monitoring/components/graph.vue b/app/assets/javascripts/monitoring/components/graph.vue index 33611c408ef..5aa3865f96a 100644 --- a/app/assets/javascripts/monitoring/components/graph.vue +++ b/app/assets/javascripts/monitoring/components/graph.vue @@ -3,7 +3,7 @@ import GraphLegend from './graph/legend.vue'; import GraphFlag from './graph/flag.vue'; import GraphDeployment from './graph/deployment.vue'; - import GraphPath from './graph_path.vue'; + import GraphPath from './graph/path.vue'; import MonitoringMixin from '../mixins/monitoring_mixins'; import eventHub from '../event_hub'; import measurements from '../utils/measurements'; @@ -69,7 +69,7 @@ }, computed: { - outterViewBox() { + outerViewBox() { return `0 0 ${this.baseGraphWidth} ${this.baseGraphHeight}`; }, @@ -137,17 +137,19 @@ }, renderAxesPaths() { - this.timeSeries = createTimeSeries(this.graphData.queries[0], - this.graphWidth, - this.graphHeight, - this.graphHeightOffset); + this.timeSeries = createTimeSeries( + this.graphData.queries[0], + this.graphWidth, + this.graphHeight, + this.graphHeightOffset, + ); if (this.timeSeries.length > 3) { this.baseGraphHeight = this.baseGraphHeight += (this.timeSeries.length - 3) * 20; } const axisXScale = d3.time.scale() - .range([0, this.graphWidth]); + .range([0, this.graphWidth - 70]); const axisYScale = d3.scale.linear() .range([this.graphHeight - this.graphHeightOffset, 0]); @@ -214,7 +216,7 @@ class="prometheus-svg-container" :style="paddingBottomRootSvg"> <svg - :viewBox="outterViewBox" + :viewBox="outerViewBox" ref="baseSvg"> <g class="x-axis" diff --git a/app/assets/javascripts/monitoring/components/graph_path.vue b/app/assets/javascripts/monitoring/components/graph/path.vue index 043f1bf66bb..043f1bf66bb 100644 --- a/app/assets/javascripts/monitoring/components/graph_path.vue +++ b/app/assets/javascripts/monitoring/components/graph/path.vue diff --git a/app/assets/javascripts/pipelines/components/pipeline_url.vue b/app/assets/javascripts/pipelines/components/pipeline_url.vue index 76b97af39f1..9da0aac50a1 100644 --- a/app/assets/javascripts/pipelines/components/pipeline_url.vue +++ b/app/assets/javascripts/pipelines/components/pipeline_url.vue @@ -72,6 +72,13 @@ :title="pipeline.yaml_errors"> yaml invalid </span> + <span + v-if="pipeline.flags.failure_reason" + v-tooltip + class="js-pipeline-url-failure label label-danger" + :title="pipeline.failure_reason"> + error + </span> <a v-if="pipeline.flags.auto_devops" tabindex="0" diff --git a/app/assets/stylesheets/pages/environments.scss b/app/assets/stylesheets/pages/environments.scss index 6a9c2578d95..3b5e411e2c5 100644 --- a/app/assets/stylesheets/pages/environments.scss +++ b/app/assets/stylesheets/pages/environments.scss @@ -291,8 +291,14 @@ fill: $black; } - .tick > text { - font-size: 12px; + .tick { + > line { + stroke: $gray-darker; + } + + > text { + font-size: 12px; + } } .text-metric-title { diff --git a/app/assets/stylesheets/pages/profile.scss b/app/assets/stylesheets/pages/profile.scss index 6c521bb06ee..eab39f698c3 100644 --- a/app/assets/stylesheets/pages/profile.scss +++ b/app/assets/stylesheets/pages/profile.scss @@ -108,6 +108,15 @@ } } +.subkeys-list { + @include basic-list; + + li { + padding: 3px 0; + border: none; + } +} + .key-list-item { .key-list-item-info { @media (min-width: $screen-sm-min) { diff --git a/app/controllers/profiles/gpg_keys_controller.rb b/app/controllers/profiles/gpg_keys_controller.rb index 689c76059f6..38e3eacd229 100644 --- a/app/controllers/profiles/gpg_keys_controller.rb +++ b/app/controllers/profiles/gpg_keys_controller.rb @@ -2,7 +2,7 @@ class Profiles::GpgKeysController < Profiles::ApplicationController before_action :set_gpg_key, only: [:destroy, :revoke] def index - @gpg_keys = current_user.gpg_keys + @gpg_keys = current_user.gpg_keys.with_subkeys @gpg_key = GpgKey.new end diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 3d5acc00f8f..cf3ce3c9e54 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -5,6 +5,7 @@ module Ci include Importable include AfterCommitQueue include Presentable + include Gitlab::OptimisticLocking belongs_to :project belongs_to :user @@ -58,6 +59,11 @@ module Ci auto_devops_source: 2 } + enum failure_reason: { + unknown_failure: 0, + config_error: 1 + } + state_machine :status, initial: :created do event :enqueue do transition created: :pending @@ -109,6 +115,12 @@ module Ci pipeline.auto_canceled_by = nil end + before_transition any => :failed do |pipeline, transition| + transition.args.first.try do |reason| + pipeline.failure_reason = reason + end + end + after_transition [:created, :pending] => :running do |pipeline| pipeline.run_after_commit { PipelineMetricsWorker.perform_async(pipeline.id) } end @@ -263,7 +275,7 @@ module Ci end def cancel_running - Gitlab::OptimisticLocking.retry_lock(cancelable_statuses) do |cancelable| + retry_optimistic_lock(cancelable_statuses) do |cancelable| cancelable.find_each do |job| yield(job) if block_given? job.cancel @@ -312,6 +324,10 @@ module Ci @stage_seeds ||= config_processor.stage_seeds(self) end + def seeds_size + @seeds_size ||= stage_seeds.sum(&:size) + end + def has_kubernetes_active? project.kubernetes_service&.active? end @@ -403,7 +419,7 @@ module Ci end def update_status - Gitlab::OptimisticLocking.retry_lock(self) do + retry_optimistic_lock(self) do case latest_builds_status when 'pending' then enqueue when 'running' then run diff --git a/app/models/concerns/has_status.rb b/app/models/concerns/has_status.rb index 3803e18a96e..7c3ed96bc28 100644 --- a/app/models/concerns/has_status.rb +++ b/app/models/concerns/has_status.rb @@ -81,6 +81,7 @@ module HasStatus scope :canceled, -> { where(status: 'canceled') } scope :skipped, -> { where(status: 'skipped') } scope :manual, -> { where(status: 'manual') } + scope :alive, -> { where(status: [:created, :pending, :running]) } scope :created_or_pending, -> { where(status: [:created, :pending]) } scope :running_or_pending, -> { where(status: [:running, :pending]) } scope :finished, -> { where(status: [:success, :failed, :canceled]) } diff --git a/app/models/gpg_key.rb b/app/models/gpg_key.rb index 54bd5b68777..44eda741679 100644 --- a/app/models/gpg_key.rb +++ b/app/models/gpg_key.rb @@ -9,6 +9,9 @@ class GpgKey < ActiveRecord::Base belongs_to :user has_many :gpg_signatures + has_many :subkeys, class_name: 'GpgKeySubkey' + + scope :with_subkeys, -> { includes(:subkeys) } validates :user, presence: true @@ -36,10 +39,12 @@ class GpgKey < ActiveRecord::Base before_validation :extract_fingerprint, :extract_primary_keyid after_commit :update_invalid_gpg_signatures, on: :create + after_create :generate_subkeys def primary_keyid super&.upcase end + alias_method :keyid, :primary_keyid def fingerprint super&.upcase @@ -49,6 +54,10 @@ class GpgKey < ActiveRecord::Base super(value&.strip) end + def keyids + [keyid].concat(subkeys.map(&:keyid)) + end + def user_infos @user_infos ||= Gitlab::Gpg.user_infos_from_key(key) end @@ -82,10 +91,11 @@ class GpgKey < ActiveRecord::Base def revoke GpgSignature - .where(gpg_key: self) + .with_key_and_subkeys(self) .where.not(verification_status: GpgSignature.verification_statuses[:unknown_key]) .update_all( gpg_key_id: nil, + gpg_key_subkey_id: nil, verification_status: GpgSignature.verification_statuses[:unknown_key], updated_at: Time.zone.now ) @@ -106,4 +116,12 @@ class GpgKey < ActiveRecord::Base # only allows one key self.primary_keyid = Gitlab::Gpg.primary_keyids_from_key(key).first end + + def generate_subkeys + gpg_subkeys = Gitlab::Gpg.subkeys_from_key(key) + + gpg_subkeys[primary_keyid]&.each do |subkey_data| + subkeys.create!(keyid: subkey_data[:keyid], fingerprint: subkey_data[:fingerprint]) + end + end end diff --git a/app/models/gpg_key_subkey.rb b/app/models/gpg_key_subkey.rb new file mode 100644 index 00000000000..b57922aba30 --- /dev/null +++ b/app/models/gpg_key_subkey.rb @@ -0,0 +1,22 @@ +class GpgKeySubkey < ActiveRecord::Base + include ShaAttribute + + sha_attribute :keyid + sha_attribute :fingerprint + + belongs_to :gpg_key + + validates :gpg_key_id, presence: true + validates :fingerprint, :keyid, presence: true, uniqueness: true + + delegate :key, :user, :user_infos, :verified?, :verified_user_infos, + :verified_and_belongs_to_email?, to: :gpg_key + + def keyid + super&.upcase + end + + def fingerprint + super&.upcase + end +end diff --git a/app/models/gpg_signature.rb b/app/models/gpg_signature.rb index 1f047a32c84..675e7a2456d 100644 --- a/app/models/gpg_signature.rb +++ b/app/models/gpg_signature.rb @@ -15,11 +15,42 @@ class GpgSignature < ActiveRecord::Base belongs_to :project belongs_to :gpg_key + belongs_to :gpg_key_subkey validates :commit_sha, presence: true validates :project_id, presence: true validates :gpg_key_primary_keyid, presence: true + def self.with_key_and_subkeys(gpg_key) + subkey_ids = gpg_key.subkeys.pluck(:id) + + where( + arel_table[:gpg_key_id].eq(gpg_key.id).or( + arel_table[:gpg_key_subkey_id].in(subkey_ids) + ) + ) + end + + def gpg_key=(model) + case model + when GpgKey + super + when GpgKeySubkey + self.gpg_key_subkey = model + when NilClass + super + self.gpg_key_subkey = nil + end + end + + def gpg_key + if gpg_key_id + super + elsif gpg_key_subkey_id + gpg_key_subkey + end + end + def gpg_key_primary_keyid super&.upcase end diff --git a/app/presenters/ci/pipeline_presenter.rb b/app/presenters/ci/pipeline_presenter.rb index a542bdd8295..099b4720fb6 100644 --- a/app/presenters/ci/pipeline_presenter.rb +++ b/app/presenters/ci/pipeline_presenter.rb @@ -1,7 +1,18 @@ module Ci class PipelinePresenter < Gitlab::View::Presenter::Delegated + FAILURE_REASONS = { + config_error: 'CI/CD YAML configuration error!' + }.freeze + presents :pipeline + def failure_reason + return unless pipeline.failure_reason? + + FAILURE_REASONS[pipeline.failure_reason.to_sym] || + pipeline.failure_reason + end + def status_title if auto_canceled? "Pipeline is redundant and is auto-canceled by Pipeline ##{auto_canceled_by_id}" diff --git a/app/serializers/pipeline_entity.rb b/app/serializers/pipeline_entity.rb index 357fc71f877..6457294b285 100644 --- a/app/serializers/pipeline_entity.rb +++ b/app/serializers/pipeline_entity.rb @@ -20,6 +20,7 @@ class PipelineEntity < Grape::Entity expose :has_yaml_errors?, as: :yaml_errors expose :can_retry?, as: :retryable expose :can_cancel?, as: :cancelable + expose :failure_reason?, as: :failure_reason end expose :details do @@ -44,6 +45,11 @@ class PipelineEntity < Grape::Entity end expose :commit, using: CommitEntity + expose :yaml_errors, if: -> (pipeline, _) { pipeline.has_yaml_errors? } + + expose :failure_reason, if: -> (pipeline, _) { pipeline.failure_reason? } do |pipeline| + pipeline.present.failure_reason + end expose :retry_path, if: -> (*) { can_retry? } do |pipeline| retry_project_pipeline_path(pipeline.project, pipeline) @@ -53,8 +59,6 @@ class PipelineEntity < Grape::Entity cancel_project_pipeline_path(pipeline.project, pipeline) end - expose :yaml_errors, if: -> (pipeline, _) { pipeline.has_yaml_errors? } - private alias_method :pipeline, :object diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml index 0d5350f873b..f1b32274664 100644 --- a/app/views/layouts/_head.html.haml +++ b/app/views/layouts/_head.html.haml @@ -37,7 +37,7 @@ - if content_for?(:library_javascripts) = yield :library_javascripts - = javascript_include_tag asset_path("locale/#{I18n.locale.to_s || I18n.default_locale.to_s}/app.js") + = javascript_include_tag asset_path("locale/#{I18n.locale.to_s || I18n.default_locale.to_s}/app.js") unless I18n.locale == :en = webpack_bundle_tag "webpack_runtime" = webpack_bundle_tag "common" = webpack_bundle_tag "main" diff --git a/app/views/profiles/gpg_keys/_key.html.haml b/app/views/profiles/gpg_keys/_key.html.haml index 970e92aadaa..5ed517c1ef6 100644 --- a/app/views/profiles/gpg_keys/_key.html.haml +++ b/app/views/profiles/gpg_keys/_key.html.haml @@ -7,6 +7,13 @@ .description %code= key.fingerprint + - if key.subkeys.present? + .subkeys + %span.bold Subkeys: + %ul.subkeys-list + - key.subkeys.each do |subkey| + %li + %code= subkey.fingerprint .pull-right %span.key-created-at created #{time_ago_with_tooltip(key.created_at)} diff --git a/app/views/projects/snippets/show.html.haml b/app/views/projects/snippets/show.html.haml index fda068f08c2..7062c5b765e 100644 --- a/app/views/projects/snippets/show.html.haml +++ b/app/views/projects/snippets/show.html.haml @@ -1,5 +1,5 @@ - @content_class = "limit-container-width limited-inner-width-container" unless fluid_layout -- add_to_breadcrumbs "Snippets", dashboard_snippets_path +- add_to_breadcrumbs "Snippets", project_snippets_path(@project) - breadcrumb_title @snippet.to_reference - page_title "#{@snippet.title} (#{@snippet.to_reference})", "Snippets" |