summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab/ci/frontend.gitlab-ci.yml2
-rw-r--r--app/assets/javascripts/boards/index.js2
-rw-r--r--app/assets/javascripts/boards/stores/state.js1
-rw-r--r--app/models/project.rb2
-rw-r--r--app/models/project_services/asana_service.rb2
-rw-r--r--app/services/metrics/dashboard/pod_dashboard_service.rb10
-rw-r--r--app/views/shared/boards/_show.html.haml1
-rw-r--r--changelogs/unreleased/36103-links-to-design-comments-from-todos-and-system-notes-do-not-jump-to.yml5
-rw-r--r--changelogs/unreleased/managed-cluster-applications-ci-template-ensure-namespace.yml5
-rw-r--r--config/prometheus/pod_metrics.yml59
-rw-r--r--db/migrate/20191216094119_add_id_to_plan_limits.rb13
-rw-r--r--db/migrate/20191216183531_add_project_hooks_to_plan_limits.rb9
-rw-r--r--db/migrate/20191216183532_insert_project_hooks_plan_limits.rb25
-rw-r--r--db/schema.rb3
-rw-r--r--doc/administration/gitaly/index.md99
-rw-r--r--doc/policy/maintenance.md4
-rw-r--r--doc/user/project/integrations/webhooks.md14
-rw-r--r--doc/user/project/operations/error_tracking.md4
-rw-r--r--doc/user/project/operations/img/error_tracking_list.pngbin760603 -> 0 bytes
-rw-r--r--doc/user/project/operations/img/error_tracking_list_v12_6.pngbin0 -> 41388 bytes
-rw-r--r--lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Managed-Cluster-Applications.gitlab-ci.yml1
-rw-r--r--lib/gitlab/database/migration_helpers.rb9
-rw-r--r--lib/gitlab/metrics/dashboard/service_selector.rb5
-rw-r--r--locale/gitlab.pot12
-rw-r--r--rubocop/cop/migration/add_column.rb5
-rw-r--r--spec/fixtures/lib/gitlab/metrics/dashboard/schemas/panel_groups.json1
-rw-r--r--spec/frontend/lib/utils/url_utility_spec.js62
-rw-r--r--spec/lib/gitlab/database/migration_helpers_spec.rb13
-rw-r--r--spec/lib/gitlab/metrics/dashboard/service_selector_spec.rb6
-rw-r--r--spec/migrations/insert_project_hooks_plan_limits_spec.rb67
-rw-r--r--spec/services/metrics/dashboard/pod_dashboard_service_spec.rb24
-rw-r--r--spec/support/helpers/metrics_dashboard_helpers.rb4
33 files changed, 430 insertions, 41 deletions
diff --git a/.gitlab/ci/frontend.gitlab-ci.yml b/.gitlab/ci/frontend.gitlab-ci.yml
index 5bd19309528..6578eec8234 100644
--- a/.gitlab/ci/frontend.gitlab-ci.yml
+++ b/.gitlab/ci/frontend.gitlab-ci.yml
@@ -74,7 +74,6 @@ gitlab:assets:compile pull-cache:
- .default-before_script
- .assets-compile-cache
- .only:changes-code-backstage-qa
- - .use-pg9
stage: prepare
script:
- node --version
@@ -83,6 +82,7 @@ gitlab:assets:compile pull-cache:
- retry bundle exec rake gitlab:assets:compile
- scripts/clean-old-cached-assets
variables:
+ SETUP_DB: "false"
# we override the max_old_space_size to prevent OOM errors
NODE_OPTIONS: --max_old_space_size=3584
cache:
diff --git a/app/assets/javascripts/boards/index.js b/app/assets/javascripts/boards/index.js
index 0d10c896a47..f1b481fc386 100644
--- a/app/assets/javascripts/boards/index.js
+++ b/app/assets/javascripts/boards/index.js
@@ -68,6 +68,8 @@ export default () => {
Board,
BoardSidebar,
BoardAddIssuesModal,
+ BoardSettingsSidebar: () =>
+ import('ee_component/boards/components/board_settings_sidebar.vue'),
},
store,
data: {
diff --git a/app/assets/javascripts/boards/stores/state.js b/app/assets/javascripts/boards/stores/state.js
index 24f44dc5629..731aea996fb 100644
--- a/app/assets/javascripts/boards/stores/state.js
+++ b/app/assets/javascripts/boards/stores/state.js
@@ -1,3 +1,4 @@
export default () => ({
isShowingLabels: true,
+ activeListId: 0,
});
diff --git a/app/models/project.rb b/app/models/project.rb
index bc8757ea888..cfdcdbed502 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -334,7 +334,7 @@ class Project < ApplicationRecord
delegate :add_guest, :add_reporter, :add_developer, :add_maintainer, :add_role, to: :team
delegate :add_master, to: :team # @deprecated
delegate :group_runners_enabled, :group_runners_enabled=, :group_runners_enabled?, to: :ci_cd_settings
- delegate :root_ancestor, to: :namespace, allow_nil: true
+ delegate :root_ancestor, :actual_limits, to: :namespace, allow_nil: true
delegate :last_pipeline, to: :commit, allow_nil: true
delegate :external_dashboard_url, to: :metrics_setting, allow_nil: true, prefix: true
delegate :default_git_depth, :default_git_depth=, to: :ci_cd_settings, prefix: :ci
diff --git a/app/models/project_services/asana_service.rb b/app/models/project_services/asana_service.rb
index 757b2f17fb9..c4fcdcc05c5 100644
--- a/app/models/project_services/asana_service.rb
+++ b/app/models/project_services/asana_service.rb
@@ -24,7 +24,7 @@ get the commit comment added to it.
You can also close a task with a message containing: `fix #123456`.
You can create a Personal Access Token here:
-http://app.asana.com/-/account_api'
+https://app.asana.com/0/developer-console'
end
def self.to_param
diff --git a/app/services/metrics/dashboard/pod_dashboard_service.rb b/app/services/metrics/dashboard/pod_dashboard_service.rb
new file mode 100644
index 00000000000..16b87d2d587
--- /dev/null
+++ b/app/services/metrics/dashboard/pod_dashboard_service.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+module Metrics
+ module Dashboard
+ class PodDashboardService < ::Metrics::Dashboard::PredefinedDashboardService
+ DASHBOARD_PATH = 'config/prometheus/pod_metrics.yml'
+ DASHBOARD_NAME = 'Pod Health'
+ end
+ end
+end
diff --git a/app/views/shared/boards/_show.html.haml b/app/views/shared/boards/_show.html.haml
index 93fc839a371..7f62b983bfc 100644
--- a/app/views/shared/boards/_show.html.haml
+++ b/app/views/shared/boards/_show.html.haml
@@ -29,6 +29,7 @@
":board-id" => "boardId",
":key" => "list.id" }
= render "shared/boards/components/sidebar", group: group
+ = render_if_exists 'shared/boards/components/board_settings_sidebar'
- if @project
%board-add-issues-modal{ "new-issue-path" => new_project_issue_path(@project),
"milestone-path" => milestones_filter_dropdown_path,
diff --git a/changelogs/unreleased/36103-links-to-design-comments-from-todos-and-system-notes-do-not-jump-to.yml b/changelogs/unreleased/36103-links-to-design-comments-from-todos-and-system-notes-do-not-jump-to.yml
new file mode 100644
index 00000000000..0c7941af93a
--- /dev/null
+++ b/changelogs/unreleased/36103-links-to-design-comments-from-todos-and-system-notes-do-not-jump-to.yml
@@ -0,0 +1,5 @@
+---
+title: Links to design comments now lead to specific note
+merge_request: 21724
+author:
+type: fixed
diff --git a/changelogs/unreleased/managed-cluster-applications-ci-template-ensure-namespace.yml b/changelogs/unreleased/managed-cluster-applications-ci-template-ensure-namespace.yml
new file mode 100644
index 00000000000..edc79f76b87
--- /dev/null
+++ b/changelogs/unreleased/managed-cluster-applications-ci-template-ensure-namespace.yml
@@ -0,0 +1,5 @@
+---
+title: Ensure namespace is present for Managed-Cluster-Applications CI template
+merge_request: 21903
+author:
+type: fixed
diff --git a/config/prometheus/pod_metrics.yml b/config/prometheus/pod_metrics.yml
new file mode 100644
index 00000000000..29575ec543e
--- /dev/null
+++ b/config/prometheus/pod_metrics.yml
@@ -0,0 +1,59 @@
+dashboard: 'Pod metrics'
+priority: 10
+panel_groups:
+- group: CPU metrics
+ panels:
+ - title: "CPU usage"
+ type: "line-chart"
+ y_label: "Cores per pod"
+ metrics:
+ - id: pod_cpu_usage_seconds_total
+ query_range: 'rate(container_cpu_usage_seconds_total{pod_name="{{pod_name}}",container_name="POD"}[5m])'
+ unit: "cores"
+ label: pod_name
+- group: Memory metrics
+ panels:
+ - title: "Memory usage working set"
+ type: "line-chart"
+ y_label: "Working set memory (MiB)"
+ metrics:
+ - id: pod_memory_working_set
+ query_range: 'container_memory_working_set_bytes{pod_name="{{pod_name}}",container_name="POD"}/1024/1024'
+ unit: "MiB"
+ label: pod_name
+- group: Network metrics
+ panels:
+ - title: "Network Receive (In)"
+ type: "line-chart"
+ y_label: "Received (KiB/sec)"
+ metrics:
+ - id: pod_network_receive
+ query_range: 'rate(container_network_receive_bytes_total{pod_name="{{pod_name}}",container_name="POD"}[5m])/1024'
+ unit: "KiB / sec"
+ label: pod_name
+ - title: "Network Transmit (Out)"
+ type: "line-chart"
+ y_label: "Transmitted (KiB/sec)"
+ metrics:
+ - id: pod_network_transmit
+ query_range: 'rate(container_network_transmit_bytes_total{pod_name="{{pod_name}}",container_name="POD"}[5m])/1024'
+ unit: "KiB / sec"
+ label: pod_name
+- group: Disk metrics
+ panels:
+ - title: "Disk Reads"
+ type: "line-chart"
+ y_label: "Disk reads (KiB/sec)"
+ metrics:
+ - id: pod_disk_reads
+ query_range: 'rate(container_fs_reads_bytes_total{container_name="POD",pod_name="{{pod_name}}"}[5m])/1024'
+ unit: "KiB / sec"
+ label: pod_name
+ - title: "Disk Writes"
+ type: "line-chart"
+ y_label: "Disk writes (KiB/sec)"
+ metrics:
+ - id: pod_disk_writes
+ query_range: 'rate(container_fs_writes_bytes_total{container_name="POD",pod_name="{{pod_name}}"}[5m])/1024'
+ unit: "KiB / sec"
+ label: pod_name
diff --git a/db/migrate/20191216094119_add_id_to_plan_limits.rb b/db/migrate/20191216094119_add_id_to_plan_limits.rb
new file mode 100644
index 00000000000..05ebd900df3
--- /dev/null
+++ b/db/migrate/20191216094119_add_id_to_plan_limits.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddIdToPlanLimits < ActiveRecord::Migration[5.2]
+ DOWNTIME = false
+
+ def up
+ add_column(:plan_limits, :id, :primary_key) unless column_exists?(:plan_limits, :id)
+ end
+
+ def down
+ remove_column(:plan_limits, :id)
+ end
+end
diff --git a/db/migrate/20191216183531_add_project_hooks_to_plan_limits.rb b/db/migrate/20191216183531_add_project_hooks_to_plan_limits.rb
new file mode 100644
index 00000000000..c56b6edf029
--- /dev/null
+++ b/db/migrate/20191216183531_add_project_hooks_to_plan_limits.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddProjectHooksToPlanLimits < ActiveRecord::Migration[5.2]
+ DOWNTIME = false
+
+ def change
+ add_column(:plan_limits, :project_hooks, :integer, default: 0, null: false)
+ end
+end
diff --git a/db/migrate/20191216183532_insert_project_hooks_plan_limits.rb b/db/migrate/20191216183532_insert_project_hooks_plan_limits.rb
new file mode 100644
index 00000000000..b2c0121dd24
--- /dev/null
+++ b/db/migrate/20191216183532_insert_project_hooks_plan_limits.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+class InsertProjectHooksPlanLimits < ActiveRecord::Migration[5.2]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def up
+ return unless Gitlab.com?
+
+ create_or_update_plan_limit('project_hooks', 'free', 10)
+ create_or_update_plan_limit('project_hooks', 'bronze', 20)
+ create_or_update_plan_limit('project_hooks', 'silver', 30)
+ create_or_update_plan_limit('project_hooks', 'gold', 100)
+ end
+
+ def down
+ return unless Gitlab.com?
+
+ create_or_update_plan_limit('project_hooks', 'free', 0)
+ create_or_update_plan_limit('project_hooks', 'bronze', 0)
+ create_or_update_plan_limit('project_hooks', 'silver', 0)
+ create_or_update_plan_limit('project_hooks', 'gold', 0)
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 7b0ecce825c..d3e9f66c388 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 2019_12_14_175727) do
+ActiveRecord::Schema.define(version: 2019_12_16_183532) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_trgm"
@@ -2987,6 +2987,7 @@ ActiveRecord::Schema.define(version: 2019_12_14_175727) do
t.integer "ci_active_pipelines", default: 0, null: false
t.integer "ci_pipeline_size", default: 0, null: false
t.integer "ci_active_jobs", default: 0, null: false
+ t.integer "project_hooks", default: 0, null: false
t.index ["plan_id"], name: "index_plan_limits_on_plan_id", unique: true
end
diff --git a/doc/administration/gitaly/index.md b/doc/administration/gitaly/index.md
index c544c531d9f..9218ffa4006 100644
--- a/doc/administration/gitaly/index.md
+++ b/doc/administration/gitaly/index.md
@@ -719,6 +719,105 @@ result as you did in the beginning:
Note that `enforced="true"`, meaning that authentication is being enforced.
+## Direct Git access in GitLab Rails
+
+Also known as "the Rugged patches".
+
+### History
+
+Before Gitaly existed, the things that are now Gitaly clients used to
+access Git repositories directly. Either on a local disk in the case of
+e.g. a single-machine Omnibus GitLab installation, or via NFS in the
+case of a horizontally scaled GitLab installation.
+
+Besides running plain `git` commands, in GitLab Rails we also used to
+use a Ruby gem (library) called
+[Rugged](https://github.com/libgit2/rugged). Rugged is a wrapper around
+[libgit2](https://libgit2.org/), a stand-alone implementation of Git in
+the form of a C library.
+
+Over time it has become clear to use that Rugged, and particularly
+Rugged in combination with the [Unicorn](https://bogomips.org/unicorn/)
+web server, is extremely efficient. Because libgit2 is a *library* and
+not an external process, there was very little overhead between GitLab
+application code that tried to look up data in Git repositories, and the
+Git implementation itself.
+
+Because Rugged+Unicorn was so efficient, GitLab's application code ended
+up with lots of duplicate Git object lookups (like looking up the
+`master` commmit a dozen times in one request). We could write
+inefficient code without being punished for it.
+
+When we migrated these Git lookups to Gitaly calls, we were suddenly
+getting a much higher fixed cost per Git lookup. Even when Gitaly is
+able to re-use an already-running `git` process to look up e.g. a commit
+you still have the cost of a network roundtrip to Gitaly, and within
+Gitaly a write/read roundtrip on the Unix pipes that connect Gitaly to
+the `git` process.
+
+Using GitLab.com performance as our yardstick, we pushed down the number
+of Gitaly calls per request until the loss of Rugged's efficiency was no
+longer felt. It also helped that we run Gitaly itself directly on the
+Git file severs, rather than via NFS mounts: this gave us a speed boost
+that counteracted the negative effect of not using Rugged anymore.
+
+Unfortunately, some *other* deployments of GitLab could not ditch NFS
+like we did on GitLab.com and they got the worst of both worlds: the
+slowness of NFS and the increased inherent overhead of Gitaly.
+
+As a performance band-aid for these stuck-on-NFS deployments, we
+re-introduced some of the old Rugged code that got deleted from
+GitLab Rails during the Gitaly migration project. These pieces of
+re-introduced code are informally referred to as "the Rugged patches".
+
+### Activation of direct Git access in GitLab Rails
+
+The Ruby methods that perform direct Git access are hidden behind [feature
+flags](../../development/gitaly.md#legacy-rugged-code). These feature
+flags are off by default. It is not good if you need to know about
+feature flags to get the best performance so in a second iteration, we
+added an automatic mechanism that will enable direct Git access.
+
+When GitLab Rails calls a function that has a Rugged patch it performs
+two checks. The result of both of these checks is cached.
+
+1. Is the feature flag for this patch set in the database? If so, do
+ what the feature flag says.
+1. If the feature flag is not set (i.e. neither true nor false), try to
+ see if we can access filesystem underneath the Gitaly server
+ directly. If so, use the Rugged patch.
+
+To see if GitLab Rails can access the repo filesystem directly, we use
+the following heuristic:
+
+- Gitaly ensures that the filesystem has a metadata file in its root
+ with a UUID in it.
+- Gitaly reports this UUID to GitLab Rails via the `ServerInfo` RPC.
+- GitLab Rails tries to read the metadata file directly. If it exists,
+ and if the UUID's match, assume we have direct access.
+
+Because of the way the UUID check works, and because Omnibus GitLab will
+fill in the correct repository paths in the GitLab Rails config file
+`config/gitlab.yml`, **direct Git access in GitLab Rails is on by default in
+Omnibus**.
+
+### Plans to remove direct Git access in GitLab Rails
+
+For the sake of removing complexity it is desirable that we get rid of
+direct Git access in GitLab Rails. For as long as some GitLab installations are stuck
+with Git repositories on slow NFS, however, we cannot just remove them.
+
+There are two prongs to our efforts to remove direct Git access in GitLab Rails:
+
+1. Reduce the number of (inefficient) Gitaly queries made by
+ GitLab Rails.
+1. Persuade everybody who runs a Highly Available / horizontally scaled
+ GitLab installation to move off of NFS.
+
+The second prong is the only real solution. For this we need [Gitaly
+HA](https://gitlab.com/groups/gitlab-org/-/epics?scope=all&utf8=%E2%9C%93&state=opened&label_name[]=Gitaly%20HA),
+which is still under development as of December 2019.
+
## Troubleshooting Gitaly
### Checking versions when using standalone Gitaly nodes
diff --git a/doc/policy/maintenance.md b/doc/policy/maintenance.md
index eb1193a50bd..7617d0c8881 100644
--- a/doc/policy/maintenance.md
+++ b/doc/policy/maintenance.md
@@ -142,7 +142,6 @@ that could change behavior in the next major release.
To ensure background migrations are successful, increment by one minor version during the version jump before installing newer releases.
For example: `11.11.x` -> `12.0.x`
-
Please see the table below for some examples:
| Latest stable version | Your version | Recommended upgrade path | Note |
@@ -152,6 +151,9 @@ Please see the table below for some examples:
| 11.3.4 | 8.13.4 | `8.13.4` -> `8.17.7` -> `9.5.10` -> `10.8.7` -> `11.3.4` | `8.17.7` is the last version in version `8`, `9.5.10` is the last version in version `9`, `10.8.7` is the last version in version `10` |
| 12.5.8 | 11.3.4 | `11.3.4` -> `11.11.8` -> `12.0.9` -> `12.5.8` | `11.11.8` is the last version in version `11` |
+To check the size of `background_migration` queue and to learn more about background migrations
+see [Upgrading without downtime](../update/README.md#upgrading-without-downtime).
+
More information about the release procedures can be found in our
[release documentation](https://gitlab.com/gitlab-org/release/docs). You may also want to read our
[Responsible Disclosure Policy](https://about.gitlab.com/security/disclosure/).
diff --git a/doc/user/project/integrations/webhooks.md b/doc/user/project/integrations/webhooks.md
index f371f2ac288..bb946574371 100644
--- a/doc/user/project/integrations/webhooks.md
+++ b/doc/user/project/integrations/webhooks.md
@@ -47,6 +47,20 @@ and **per project and per group** for **GitLab Enterprise Edition**.
Navigate to the webhooks page by going to your project's
**Settings ➔ Integrations**.
+## Maximum number of webhooks (per tier)
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/20730) in GitLab 12.6.
+
+A maximum number of project webhooks applies to each [GitLab.com
+tier](https://about.gitlab.com/pricing/), as shown in the following table:
+
+| Tier | Number of webhooks per project |
+|----------|--------------------------------|
+| Free | 10 |
+| Bronze | 20 |
+| Silver | 30 |
+| Gold | 100 |
+
## Use-cases
- You can set up a webhook in GitLab to send a notification to
diff --git a/doc/user/project/operations/error_tracking.md b/doc/user/project/operations/error_tracking.md
index 230e388d497..912d7fdbef5 100644
--- a/doc/user/project/operations/error_tracking.md
+++ b/doc/user/project/operations/error_tracking.md
@@ -42,9 +42,9 @@ NOTE: **Note:**
You will need at least Reporter [permissions](../../permissions.md) to view the Error Tracking list.
The Error Tracking list may be found at **Operations > Error Tracking** in your project's sidebar.
-Errors can be filtered by title.
+Errors can be filtered by title or sorted by Frequency, First Seen or Last Seen. Errors are always sorted in descending order by the field specified.
-![Error Tracking list](img/error_tracking_list.png)
+![Error Tracking list](img/error_tracking_list_v12_6.png)
## Error Details
diff --git a/doc/user/project/operations/img/error_tracking_list.png b/doc/user/project/operations/img/error_tracking_list.png
deleted file mode 100644
index 79b464e021e..00000000000
--- a/doc/user/project/operations/img/error_tracking_list.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/operations/img/error_tracking_list_v12_6.png b/doc/user/project/operations/img/error_tracking_list_v12_6.png
new file mode 100644
index 00000000000..b99c83c14d3
--- /dev/null
+++ b/doc/user/project/operations/img/error_tracking_list_v12_6.png
Binary files differ
diff --git a/lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml
index 8f50f38bbed..1708984c1cb 100644
--- a/lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml
@@ -7,7 +7,7 @@ code_quality:
variables:
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: ""
- CODE_QUALITY_IMAGE: "registry.gitlab.com/gitlab-org/security-products/codequality:12-5-stable"
+ CODE_QUALITY_IMAGE: "registry.gitlab.com/gitlab-org/security-products/codequality:0.85.5"
script:
- |
if ! docker info &>/dev/null; then
diff --git a/lib/gitlab/ci/templates/Managed-Cluster-Applications.gitlab-ci.yml b/lib/gitlab/ci/templates/Managed-Cluster-Applications.gitlab-ci.yml
index 938b6f89b76..9a5b0f79ecf 100644
--- a/lib/gitlab/ci/templates/Managed-Cluster-Applications.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Managed-Cluster-Applications.gitlab-ci.yml
@@ -9,6 +9,7 @@ apply:
INGRESS_VALUES_FILE: $CI_PROJECT_DIR/.gitlab/managed-apps/ingress/values.yaml
SENTRY_VALUES_FILE: $CI_PROJECT_DIR/.gitlab/managed-apps/sentry/values.yaml
script:
+ - kubectl get namespace "$TILLER_NAMESPACE" || kubectl create namespace "$TILLER_NAMESPACE"
- gitlab-managed-apps /usr/local/share/gitlab-managed-apps/helmfile.yaml
only:
refs:
diff --git a/lib/gitlab/database/migration_helpers.rb b/lib/gitlab/database/migration_helpers.rb
index 03bde611451..f9340b262e5 100644
--- a/lib/gitlab/database/migration_helpers.rb
+++ b/lib/gitlab/database/migration_helpers.rb
@@ -1052,6 +1052,15 @@ into similar problems in the future (e.g. when new tables are created).
connection.select_value(index_sql).to_i > 0
end
+ def create_or_update_plan_limit(limit_name, plan_name, limit_value)
+ execute <<~SQL
+ INSERT INTO plan_limits (plan_id, #{quote_column_name(limit_name)})
+ VALUES
+ ((SELECT id FROM plans WHERE name = #{quote(plan_name)} LIMIT 1), #{quote(limit_value)})
+ ON CONFLICT (plan_id) DO UPDATE SET #{quote_column_name(limit_name)} = EXCLUDED.#{quote_column_name(limit_name)};
+ SQL
+ end
+
private
def tables_match?(target_table, foreign_key_table)
diff --git a/lib/gitlab/metrics/dashboard/service_selector.rb b/lib/gitlab/metrics/dashboard/service_selector.rb
index 22314c2a0ee..5b6f25420e0 100644
--- a/lib/gitlab/metrics/dashboard/service_selector.rb
+++ b/lib/gitlab/metrics/dashboard/service_selector.rb
@@ -22,6 +22,7 @@ module Gitlab
return SERVICES::DynamicEmbedService if dynamic_embed?(params)
return SERVICES::DefaultEmbedService if params[:embedded]
return SERVICES::SystemDashboardService if system_dashboard?(params[:dashboard_path])
+ return SERVICES::PodDashboardService if pod_dashboard?(params[:dashboard_path])
return SERVICES::ProjectDashboardService if params[:dashboard_path]
default_service
@@ -37,6 +38,10 @@ module Gitlab
SERVICES::SystemDashboardService.matching_dashboard?(filepath)
end
+ def pod_dashboard?(filepath)
+ SERVICES::PodDashboardService.matching_dashboard?(filepath)
+ end
+
def custom_metric_embed?(params)
SERVICES::CustomMetricEmbedService.valid_params?(params)
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index d0cb07b3859..9fe8e8e670b 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -10223,6 +10223,9 @@ msgstr ""
msgid "Label"
msgstr ""
+msgid "Label List"
+msgstr ""
+
msgid "Label actions dropdown"
msgstr ""
@@ -10982,6 +10985,9 @@ msgstr ""
msgid "Maximum lifetime allowable for Personal Access Tokens is active, your expire date must be set before %{maximum_allowable_date}."
msgstr ""
+msgid "Maximum number of %{name} (%{count}) exceeded"
+msgstr ""
+
msgid "Maximum number of comments exceeded"
msgstr ""
@@ -18887,6 +18893,12 @@ msgstr ""
msgid "Too many changes to show."
msgstr ""
+msgid "Too many namespaces enabled. You will need to manage them via the console or the API."
+msgstr ""
+
+msgid "Too many projects enabled. You will need to manage them via the console or the API."
+msgstr ""
+
msgid "Topics"
msgstr ""
diff --git a/rubocop/cop/migration/add_column.rb b/rubocop/cop/migration/add_column.rb
index 2530d6477e8..a25bd843559 100644
--- a/rubocop/cop/migration/add_column.rb
+++ b/rubocop/cop/migration/add_column.rb
@@ -8,7 +8,10 @@ module RuboCop
class AddColumn < RuboCop::Cop::Cop
include MigrationHelpers
- WHITELISTED_TABLES = [:application_settings].freeze
+ WHITELISTED_TABLES = %i[
+ application_settings
+ plan_limits
+ ].freeze
MSG = '`add_column` with a default value requires downtime, ' \
'use `add_column_with_default` instead'.freeze
diff --git a/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/panel_groups.json b/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/panel_groups.json
index d7a390adcdc..f4afb4cbffc 100644
--- a/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/panel_groups.json
+++ b/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/panel_groups.json
@@ -2,7 +2,6 @@
"type": "object",
"required": [
"group",
- "priority",
"panels"
],
"properties": {
diff --git a/spec/frontend/lib/utils/url_utility_spec.js b/spec/frontend/lib/utils/url_utility_spec.js
index a625c9cd274..048736d75f6 100644
--- a/spec/frontend/lib/utils/url_utility_spec.js
+++ b/spec/frontend/lib/utils/url_utility_spec.js
@@ -330,46 +330,46 @@ describe('URL utility', () => {
expect(urlUtils.escapeFileUrl('foo/bar/file.md')).toBe('foo/bar/file.md');
});
});
-});
-describe('setUrlParams', () => {
- it('adds new params as query string', () => {
- const url = 'https://gitlab.com/test';
+ describe('setUrlParams', () => {
+ it('adds new params as query string', () => {
+ const url = 'https://gitlab.com/test';
- expect(
- urlUtils.setUrlParams({ group_id: 'gitlab-org', project_id: 'my-project' }, url),
- ).toEqual('https://gitlab.com/test?group_id=gitlab-org&project_id=my-project');
- });
+ expect(
+ urlUtils.setUrlParams({ group_id: 'gitlab-org', project_id: 'my-project' }, url),
+ ).toEqual('https://gitlab.com/test?group_id=gitlab-org&project_id=my-project');
+ });
- it('updates an existing parameter', () => {
- const url = 'https://gitlab.com/test?group_id=gitlab-org&project_id=my-project';
+ it('updates an existing parameter', () => {
+ const url = 'https://gitlab.com/test?group_id=gitlab-org&project_id=my-project';
- expect(urlUtils.setUrlParams({ project_id: 'gitlab-test' }, url)).toEqual(
- 'https://gitlab.com/test?group_id=gitlab-org&project_id=gitlab-test',
- );
- });
+ expect(urlUtils.setUrlParams({ project_id: 'gitlab-test' }, url)).toEqual(
+ 'https://gitlab.com/test?group_id=gitlab-org&project_id=gitlab-test',
+ );
+ });
- it("removes the project_id param when it's value is null", () => {
- const url = 'https://gitlab.com/test?group_id=gitlab-org&project_id=my-project';
+ it("removes the project_id param when it's value is null", () => {
+ const url = 'https://gitlab.com/test?group_id=gitlab-org&project_id=my-project';
- expect(urlUtils.setUrlParams({ project_id: null }, url)).toEqual(
- 'https://gitlab.com/test?group_id=gitlab-org',
- );
- });
+ expect(urlUtils.setUrlParams({ project_id: null }, url)).toEqual(
+ 'https://gitlab.com/test?group_id=gitlab-org',
+ );
+ });
- it('handles arrays properly', () => {
- const url = 'https://gitlab.com/test';
+ it('handles arrays properly', () => {
+ const url = 'https://gitlab.com/test';
- expect(urlUtils.setUrlParams({ label_name: ['foo', 'bar'] }, url)).toEqual(
- 'https://gitlab.com/test?label_name=foo&label_name=bar',
- );
- });
+ expect(urlUtils.setUrlParams({ label_name: ['foo', 'bar'] }, url)).toEqual(
+ 'https://gitlab.com/test?label_name=foo&label_name=bar',
+ );
+ });
- it('removes all existing URL params and sets a new param when cleanParams=true', () => {
- const url = 'https://gitlab.com/test?group_id=gitlab-org&project_id=my-project';
+ it('removes all existing URL params and sets a new param when cleanParams=true', () => {
+ const url = 'https://gitlab.com/test?group_id=gitlab-org&project_id=my-project';
- expect(urlUtils.setUrlParams({ foo: 'bar' }, url, true)).toEqual(
- 'https://gitlab.com/test?foo=bar',
- );
+ expect(urlUtils.setUrlParams({ foo: 'bar' }, url, true)).toEqual(
+ 'https://gitlab.com/test?foo=bar',
+ );
+ });
});
});
diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb
index 2ba253f9652..cac6908f4b4 100644
--- a/spec/lib/gitlab/database/migration_helpers_spec.rb
+++ b/spec/lib/gitlab/database/migration_helpers_spec.rb
@@ -1440,4 +1440,17 @@ describe Gitlab::Database::MigrationHelpers do
end
end
end
+
+ describe '#create_or_update_plan_limit' do
+ it 'creates or updates plan limits' do
+ expect(model).to receive(:execute).with <<~SQL
+ INSERT INTO plan_limits (plan_id, "project_hooks")
+ VALUES
+ ((SELECT id FROM plans WHERE name = 'free' LIMIT 1), '10')
+ ON CONFLICT (plan_id) DO UPDATE SET "project_hooks" = EXCLUDED."project_hooks";
+ SQL
+
+ model.create_or_update_plan_limit('project_hooks', 'free', 10)
+ end
+ end
end
diff --git a/spec/lib/gitlab/metrics/dashboard/service_selector_spec.rb b/spec/lib/gitlab/metrics/dashboard/service_selector_spec.rb
index 0d4562f78f1..e0c8133994b 100644
--- a/spec/lib/gitlab/metrics/dashboard/service_selector_spec.rb
+++ b/spec/lib/gitlab/metrics/dashboard/service_selector_spec.rb
@@ -22,6 +22,12 @@ describe Gitlab::Metrics::Dashboard::ServiceSelector do
it { is_expected.to be Metrics::Dashboard::SystemDashboardService }
end
+
+ context 'when the path is for the pod dashboard' do
+ let(:arguments) { { dashboard_path: pod_dashboard_path } }
+
+ it { is_expected.to be Metrics::Dashboard::PodDashboardService }
+ end
end
context 'when the embedded flag is provided' do
diff --git a/spec/migrations/insert_project_hooks_plan_limits_spec.rb b/spec/migrations/insert_project_hooks_plan_limits_spec.rb
new file mode 100644
index 00000000000..abc2ccd0507
--- /dev/null
+++ b/spec/migrations/insert_project_hooks_plan_limits_spec.rb
@@ -0,0 +1,67 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require Rails.root.join('db', 'migrate', '20191216183532_insert_project_hooks_plan_limits.rb')
+
+describe InsertProjectHooksPlanLimits, :migration do
+ let(:migration) { described_class.new }
+ let(:plans) { table(:plans) }
+ let(:plan_limits) { table(:plan_limits) }
+
+ before do
+ plans.create(id: 34, name: 'free')
+ plans.create(id: 2, name: 'bronze')
+ plans.create(id: 3, name: 'silver')
+ plans.create(id: 4, name: 'gold')
+ plan_limits.create(plan_id: 34, ci_active_jobs: 5)
+ end
+
+ context 'when on Gitlab.com' do
+ before do
+ expect(Gitlab).to receive(:com?).at_most(:twice).and_return(true)
+ end
+
+ describe '#up' do
+ it 'updates the project_hooks plan limits' do
+ migration.up
+
+ expect(plan_limits.pluck(:plan_id, :project_hooks, :ci_active_jobs))
+ .to match_array([[34, 10, 5], [2, 20, 0], [3, 30, 0], [4, 100, 0]])
+ end
+ end
+
+ describe '#down' do
+ it 'updates the project_hooks plan limits to 0' do
+ migration.up
+ migration.down
+
+ expect(plan_limits.pluck(:plan_id, :project_hooks, :ci_active_jobs))
+ .to match_array([[34, 0, 5], [2, 0, 0], [3, 0, 0], [4, 0, 0]])
+ end
+ end
+ end
+
+ context 'when on self-hosted' do
+ before do
+ expect(Gitlab).to receive(:com?).and_return(false)
+ end
+
+ describe '#up' do
+ it 'does not update the plan limits' do
+ migration.up
+
+ expect(plan_limits.pluck(:plan_id, :project_hooks, :ci_active_jobs))
+ .to match_array([[34, 0, 5]])
+ end
+ end
+
+ describe '#down' do
+ it 'does not update the plan limits' do
+ migration.down
+
+ expect(plan_limits.pluck(:plan_id, :project_hooks, :ci_active_jobs))
+ .to match_array([[34, 0, 5]])
+ end
+ end
+ end
+end
diff --git a/spec/services/metrics/dashboard/pod_dashboard_service_spec.rb b/spec/services/metrics/dashboard/pod_dashboard_service_spec.rb
new file mode 100644
index 00000000000..c3993bf71ea
--- /dev/null
+++ b/spec/services/metrics/dashboard/pod_dashboard_service_spec.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Metrics::Dashboard::PodDashboardService, :use_clean_rails_memory_store_caching do
+ include MetricsDashboardHelpers
+
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:environment) { create(:environment, project: project) }
+
+ before do
+ project.add_maintainer(user)
+ end
+
+ describe 'get_dashboard' do
+ let(:dashboard_path) { described_class::DASHBOARD_PATH }
+ let(:service_params) { [project, user, { environment: environment, dashboard_path: dashboard_path }] }
+ let(:service_call) { described_class.new(*service_params).get_dashboard }
+
+ it_behaves_like 'valid dashboard service response'
+ it_behaves_like 'caches the unprocessed dashboard for subsequent calls'
+ end
+end
diff --git a/spec/support/helpers/metrics_dashboard_helpers.rb b/spec/support/helpers/metrics_dashboard_helpers.rb
index 98f235bdac4..5b425d0964d 100644
--- a/spec/support/helpers/metrics_dashboard_helpers.rb
+++ b/spec/support/helpers/metrics_dashboard_helpers.rb
@@ -22,6 +22,10 @@ module MetricsDashboardHelpers
Metrics::Dashboard::SystemDashboardService::DASHBOARD_PATH
end
+ def pod_dashboard_path
+ Metrics::Dashboard::PodDashboardService::DASHBOARD_PATH
+ end
+
def business_metric_title
PrometheusMetricEnums.group_details[:business][:group_title]
end