Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2019-10-31 15:06:41 +00:00
parent 0be510a49f
commit 083d64c646
55 changed files with 1076 additions and 654 deletions

View File

@ -94,10 +94,7 @@ schedule:review-build-cng:
variables:
HOST_SUFFIX: "${CI_ENVIRONMENT_SLUG}"
DOMAIN: "-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}"
# v2.3.7 + some stability improvements not yet released:
# - sidekiq readinessProbe should be `pgrep -f sidekiq`: https://gitlab.com/gitlab-org/charts/gitlab/merge_requests/991
# - Allows livenessProbe and readinessProbe to be configured for unicorn: https://gitlab.com/gitlab-org/charts/gitlab/merge_requests/985
GITLAB_HELM_CHART_REF: "df7c52dc69df441909880b8f2fd15e938cdb2047"
GITLAB_HELM_CHART_REF: "v2.4.4"
GITLAB_EDITION: "ce"
environment:
name: review/${CI_COMMIT_REF_NAME}

View File

@ -3,21 +3,24 @@
# Provides an action which fetches a metrics dashboard according
# to the parameters specified by the controller.
module MetricsDashboard
include RenderServiceResults
extend ActiveSupport::Concern
def metrics_dashboard
result = dashboard_finder.find(
project_for_dashboard,
current_user,
metrics_dashboard_params
metrics_dashboard_params.to_h.symbolize_keys
)
if include_all_dashboards?
if include_all_dashboards? && result
result[:all_dashboards] = dashboard_finder.find_all_paths(project_for_dashboard)
end
respond_to do |format|
if result[:status] == :success
if result.nil?
format.json { continue_polling_response }
elsif result[:status] == :success
format.json { render dashboard_success_response(result) }
else
format.json { render dashboard_error_response(result) }
@ -56,7 +59,7 @@ module MetricsDashboard
def dashboard_error_response(result)
{
status: result[:http_status],
status: result[:http_status] || :bad_request,
json: result.slice(:all_dashboards, :message, :status)
}
end

View File

@ -199,8 +199,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController
def metrics_dashboard_params
params
.permit(:embedded, :group, :title, :y_label)
.to_h.symbolize_keys
.permit(:embedded, :group, :title, :y_label, :dashboard_path, :environment)
.merge(dashboard_path: params[:dashboard], environment: environment)
end

View File

@ -2,6 +2,9 @@
class Projects::GrafanaApiController < Projects::ApplicationController
include RenderServiceResults
include MetricsDashboard
before_action :validate_feature_enabled!, only: [:metrics_dashboard]
def proxy
result = ::Grafana::ProxyService.new(
@ -19,6 +22,14 @@ class Projects::GrafanaApiController < Projects::ApplicationController
private
def metrics_dashboard_params
params.permit(:embedded, :grafana_url)
end
def validate_feature_enabled!
render_403 unless Feature.enabled?(:gfm_grafana_integration)
end
def query_params
params.permit(:query, :start, :end, :step)
end

View File

@ -1,6 +1,8 @@
# frozen_string_literal: true
module SearchHelper
SEARCH_PERMITTED_PARAMS = [:search, :scope, :project_id, :group_id, :repository_ref, :snippets].freeze
def search_autocomplete_opts(term)
return unless current_user
@ -200,7 +202,7 @@ module SearchHelper
search_params = params
.merge(search)
.merge({ scope: scope })
.permit(:search, :scope, :project_id, :group_id, :repository_ref, :snippets)
.permit(SEARCH_PERMITTED_PARAMS)
if @scope == scope
li_class = 'active'

View File

@ -197,9 +197,7 @@ module TreeHelper
end
def directory_download_links(project, ref, archive_prefix)
formats = ['zip', 'tar.gz', 'tar.bz2', 'tar']
formats.map do |fmt|
Gitlab::Workhorse::ARCHIVE_FORMATS.map do |fmt|
{
text: fmt,
path: project_archive_path(project, id: tree_join(ref, archive_prefix), format: fmt)

View File

@ -6,11 +6,9 @@ module Releases
attr_accessor :project, :tag_name, :format
FORMATS = %w(zip tar.gz tar.bz2 tar).freeze
class << self
def all(project, tag_name)
Releases::Source::FORMATS.map do |format|
Gitlab::Workhorse::ARCHIVE_FORMATS.map do |format|
Releases::Source.new(project: project,
tag_name: tag_name,
format: format)

View File

@ -13,7 +13,7 @@ module Groups
TransferError = Class.new(StandardError)
attr_reader :error
attr_reader :error, :new_parent_group
def initialize(group, user, params = {})
super
@ -115,3 +115,5 @@ module Groups
end
end
end
Groups::TransferService.prepend_if_ee('EE::Groups::TransferService')

View File

@ -13,6 +13,8 @@ module Projects
include Gitlab::ShellAdapter
TransferError = Class.new(StandardError)
attr_reader :new_namespace
def execute(new_namespace)
@new_namespace = new_namespace

View File

@ -1,6 +1,4 @@
- formats = [['zip', 'btn-primary'], ['tar.gz'], ['tar.bz2'], ['tar']]
.btn-group.ml-0.w-100
- formats.each do |(fmt, extra_class)|
- Gitlab::Workhorse::ARCHIVE_FORMATS.each_with_index do |fmt, index|
- archive_path = project_archive_path(project, id: tree_join(ref, archive_prefix), path: path, format: fmt)
= link_to fmt, external_storage_url_or_path(archive_path), rel: 'nofollow', download: '', class: "btn btn-xs #{extra_class}"
= link_to fmt, external_storage_url_or_path(archive_path), rel: 'nofollow', download: '', class: "btn btn-xs #{"btn-primary" if index == 0}"

View File

@ -1,6 +1,7 @@
- if @search_objects.to_a.empty?
= render partial: "search/results/empty"
= render_if_exists 'shared/promotions/promote_advanced_search'
= render_if_exists 'search/form_revert_to_basic'
- else
.row-content-block.d-md-flex.text-left.align-items-center
- unless @search_objects.is_a?(Kaminari::PaginatableWithoutCount)

View File

@ -0,0 +1,5 @@
---
title: Use Rails 5.2 Redis caching store
merge_request: 19202
author:
type: other

View File

@ -247,7 +247,10 @@ module Gitlab
end
# Use caching across all environments
# Full list of options:
# https://api.rubyonrails.org/classes/ActiveSupport/Cache/RedisCacheStore.html#method-c-new
caching_config_hash = Gitlab::Redis::Cache.params
caching_config_hash[:compress] = false
caching_config_hash[:namespace] = Gitlab::Redis::Cache::CACHE_NAMESPACE
caching_config_hash[:expires_in] = 2.weeks # Cache should not grow forever
if Sidekiq.server? # threaded context
@ -255,7 +258,7 @@ module Gitlab
caching_config_hash[:pool_timeout] = 1
end
config.cache_store = :redis_store, caching_config_hash
config.cache_store = :redis_cache_store, caching_config_hash
config.active_job.queue_adapter = :sidekiq

View File

@ -187,9 +187,10 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
resource :import, only: [:new, :create, :show]
resource :avatar, only: [:show, :destroy]
get 'grafana/proxy/:datasource_id/*proxy_path',
to: 'grafana_api#proxy',
as: :grafana_api
scope :grafana, as: :grafana_api do
get 'proxy/:datasource_id/*proxy_path', to: 'grafana_api#proxy'
get :metrics_dashboard, to: 'grafana_api#metrics_dashboard'
end
end
# End of the /-/ scope.

View File

@ -328,6 +328,8 @@ When you tail the Gitaly logs on your Gitaly server you should see requests
coming in. One sure way to trigger a Gitaly request is to clone a repository
from your GitLab server over HTTP.
DANGER: **Danger:** If you have [custom server-side Git hooks](../custom_hooks.md#custom-server-side-git-hooks) configured, either per repository or globally, you must move these to the Gitaly node. If you have multiple Gitaly nodes, copy your custom hook(s) to all nodes.
### Disabling the Gitaly service in a cluster environment
If you are running Gitaly [as a remote

View File

@ -583,3 +583,12 @@ Here are some common pitfalls and how to overcome them:
AWS has [fixed limits](https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/aes-limits.html)
for this setting ("Maximum Size of HTTP Request Payloads"), based on the size of
the underlying instance.
### Reverting to basic search
Sometimes there may be issues with your Elasticsearch index data and as such
GitLab will allow you to revert to "basic search" when there are no search
results and assuming that basic search is supported in that scope. This "basic
search" will behave as though you don't have Elasticsearch enabled at all for
your instance and search using other data sources (ie. Postgres data and Git
data).

View File

@ -95,58 +95,85 @@ Auto DevOps.
To make full use of Auto DevOps, you will need:
- **Kubernetes** (for Auto Review Apps, Auto Deploy, and Auto Monitoring)
To enable deployments, you will need:
1. A [Kubernetes 1.5+ cluster](../../user/project/clusters/index.md) for the project. The easiest
way is to add a [new GKE cluster using the GitLab UI](../../user/project/clusters/add_remove_clusters.md#add-new-gke-cluster).
1. NGINX Ingress. You can deploy it to your Kubernetes cluster by installing
the [GitLab-managed app for Ingress](../../user/clusters/applications.md#ingress),
once you have configured GitLab's Kubernetes integration in the previous step.
Alternatively, you can use the
[`nginx-ingress`](https://github.com/helm/charts/tree/master/stable/nginx-ingress)
Helm chart to install Ingress manually.
NOTE: **Note:**
If you are using your own Ingress instead of the one provided by GitLab's managed
apps, ensure you are running at least version 0.9.0 of NGINX Ingress and
[enable Prometheus metrics](https://github.com/kubernetes/ingress-nginx/blob/master/docs/examples/customization/custom-vts-metrics-prometheus/nginx-vts-metrics-conf.yaml)
in order for the response metrics to appear. You will also have to
[annotate](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/)
the NGINX Ingress deployment to be scraped by Prometheus using
`prometheus.io/scrape: "true"` and `prometheus.io/port: "10254"`.
- **Base domain** (for Auto Review Apps, Auto Deploy, and Auto Monitoring)
You will need a domain configured with wildcard DNS which is going to be used
by all of your Auto DevOps applications. If you're using the
[GitLab-managed app for Ingress](../../user/clusters/applications.md#ingress),
the URL endpoint will be automatically configured for you.
You will then need to [specify the Auto DevOps base domain](#auto-devops-base-domain).
- **GitLab Runner** (for all stages)
Your Runner needs to be configured to be able to run Docker. Generally this
means using either the [Docker](https://docs.gitlab.com/runner/executors/docker.html)
or [Kubernetes](https://docs.gitlab.com/runner/executors/kubernetes.html) executors, with
[privileged mode enabled](https://docs.gitlab.com/runner/executors/docker.html#use-docker-in-docker-with-privileged-mode).
The Runners do not need to be installed in the Kubernetes cluster, but the
Kubernetes executor is easy to use and is automatically autoscaling.
Docker-based Runners can be configured to autoscale as well, using [Docker
Machine](https://docs.gitlab.com/runner/install/autoscaling.html).
If you have configured GitLab's Kubernetes integration in the first step, you
can deploy it to your cluster by installing the
[GitLab-managed app for GitLab Runner](../../user/clusters/applications.md#gitlab-runner).
Runners should be registered as [shared Runners](../../ci/runners/README.md#registering-a-shared-runner)
for the entire GitLab instance, or [specific Runners](../../ci/runners/README.md#registering-a-specific-runner)
that are assigned to specific projects.
- **Base domain** (for Auto Review Apps and Auto Deploy)
that are assigned to specific projects (the default if you have installed the
GitLab Runner managed application).
You will need a domain configured with wildcard DNS which is going to be used
by all of your Auto DevOps applications.
Read the [specifics](#auto-devops-base-domain).
- **Kubernetes** (for Auto Review Apps, Auto Deploy, and Auto Monitoring)
To enable deployments, you will need:
- Kubernetes 1.5+.
- A [Kubernetes cluster][kubernetes-clusters] for the project.
- A load balancer. You can use NGINX Ingress by deploying it to your
Kubernetes cluster by either:
- Using the [`nginx-ingress`](https://github.com/helm/charts/tree/master/stable/nginx-ingress) Helm chart.
- Installing the Ingress [GitLab Managed App](../../user/clusters/applications.md#ingress).
- **Prometheus** (for Auto Monitoring)
To enable Auto Monitoring, you
will need Prometheus installed somewhere (inside or outside your cluster) and
configured to scrape your Kubernetes cluster. To get response metrics
(in addition to system metrics), you need to
[configure Prometheus to monitor NGINX](../../user/project/integrations/prometheus_library/nginx_ingress.md#configuring-nginx-ingress-monitoring).
To enable Auto Monitoring, you will need Prometheus installed somewhere
(inside or outside your cluster) and configured to scrape your Kubernetes cluster.
If you have configured GitLab's Kubernetes integration, you can deploy it to
your cluster by installing the
[GitLab-managed app for Prometheus](../../user/clusters/applications.md#prometheus).
The [Prometheus service](../../user/project/integrations/prometheus.md)
integration needs to be enabled for the project, or enabled as a
integration needs to be enabled for the project (or enabled as a
[default service template](../../user/project/integrations/services_templates.md)
for the entire GitLab installation.
for the entire GitLab installation).
To get response metrics (in addition to system metrics), you need to
[configure Prometheus to monitor NGINX](../../user/project/integrations/prometheus_library/nginx_ingress.md#configuring-nginx-ingress-monitoring).
If you do not have Kubernetes or Prometheus installed, then Auto Review Apps,
Auto Deploy, and Auto Monitoring will be silently skipped.
One all requirements are met, you can go ahead and [enable Auto DevOps](#enablingdisabling-auto-devops).
## Auto DevOps base domain
The Auto DevOps base domain is required if you want to make use of [Auto
Review Apps](#auto-review-apps) and [Auto Deploy](#auto-deploy). It can be defined
in any of the following places:
The Auto DevOps base domain is required if you want to make use of
[Auto Review Apps](#auto-review-apps), [Auto Deploy](#auto-deploy), and
[Auto Monitoring](#auto-monitoring). It can be defined in any of the following
places:
- either under the cluster's settings, whether for [projects](../../user/project/clusters/index.md#base-domain) or [groups](../../user/group/clusters/index.md#base-domain)
- or in instance-wide settings in the **admin area > Settings** under the "Continuous Integration and Delivery" section
@ -156,9 +183,15 @@ in any of the following places:
The base domain variable `KUBE_INGRESS_BASE_DOMAIN` follows the same order of precedence
as other environment [variables](../../ci/variables/README.md#priority-of-environment-variables).
NOTE: **Note**
`AUTO_DEVOPS_DOMAIN` environment variable is deprecated and
[is scheduled to be removed](https://gitlab.com/gitlab-org/gitlab-foss/issues/56959).
TIP: **Tip:**
If you're using the [GitLab managed app for Ingress](../../user/clusters/applications.md#ingress),
the URL endpoint should be automatically configured for you. All you have to do
is use its value for the `KUBE_INGRESS_BASE_DOMAIN` variable.
NOTE: **Note:**
`AUTO_DEVOPS_DOMAIN` was [deprecated in GitLab 11.8](https://gitlab.com/gitlab-org/gitlab-foss/issues/52363)
and replaced with `KUBE_INGRESS_BASE_DOMAIN`. It was removed in
[GitLab 12.0](https://gitlab.com/gitlab-org/gitlab-foss/issues/56959).
A wildcard DNS A record matching the base domain(s) is required, for example,
given a base domain of `example.com`, you'd need a DNS entry like:
@ -179,10 +212,84 @@ Auto DevOps base domain to `1.2.3.4.nip.io`.
Once set up, all requests will hit the load balancer, which in turn will route
them to the Kubernetes pods that run your application(s).
NOTE: **Note:**
From GitLab 11.8, `KUBE_INGRESS_BASE_DOMAIN` replaces `AUTO_DEVOPS_DOMAIN`.
Support for `AUTO_DEVOPS_DOMAIN` was [removed in GitLab
12.0](https://gitlab.com/gitlab-org/gitlab-foss/issues/56959).
## Enabling/Disabling Auto DevOps
When first using Auto DevOps, review the [requirements](#requirements) to ensure all necessary components to make
full use of Auto DevOps are available. If this is your fist time, we recommend you follow the
[quick start guide](quick_start_guide.md).
GitLab.com users can enable/disable Auto DevOps at the project-level only. Self-managed users
can enable/disable Auto DevOps at the project-level, group-level or instance-level.
### At the project level
If enabling, check that your project doesn't have a `.gitlab-ci.yml`, or if one exists, remove it.
1. Go to your project's **Settings > CI/CD > Auto DevOps**.
1. Toggle the **Default to Auto DevOps pipeline** checkbox (checked to enable, unchecked to disable)
1. When enabling, it's optional but recommended to add in the [base domain](#auto-devops-base-domain)
that will be used by Auto DevOps to [deploy your application](#auto-deploy)
and choose the [deployment strategy](#deployment-strategy).
1. Click **Save changes** for the changes to take effect.
When the feature has been enabled, an Auto DevOps pipeline is triggered on the default branch.
### At the group level
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/52447) in GitLab 11.10.
Only administrators and group owners can enable or disable Auto DevOps at the group level.
To enable or disable Auto DevOps at the group-level:
1. Go to group's **Settings > CI/CD > Auto DevOps** page.
1. Toggle the **Default to Auto DevOps pipeline** checkbox (checked to enable, unchecked to disable).
1. Click **Save changes** button for the changes to take effect.
When enabling or disabling Auto DevOps at group-level, group configuration will be implicitly used for
the subgroups and projects inside that group, unless Auto DevOps is specifically enabled or disabled on
the subgroup or project.
### At the instance level (Administrators only)
Even when disabled at the instance level, group owners and project maintainers can still enable
Auto DevOps at the group and project level, respectively.
1. Go to **Admin area > Settings > Continuous Integration and Deployment**.
1. Toggle the checkbox labeled **Default to Auto DevOps pipeline for all projects**.
1. If enabling, optionally set up the Auto DevOps [base domain](#auto-devops-base-domain) which will be used for Auto Deploy and Auto Review Apps.
1. Click **Save changes** for the changes to take effect.
### Enable for a percentage of projects
There is also a feature flag to enable Auto DevOps by default to your chosen percentage of projects.
This can be enabled from the console with the following, which uses the example of 10%:
`Feature.get(:force_autodevops_on_by_default).enable_percentage_of_actors(10)`
### Deployment strategy
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/38542) in GitLab 11.0.
You can change the deployment strategy used by Auto DevOps by going to your
project's **Settings > CI/CD > Auto DevOps**.
The available options are:
- **Continuous deployment to production**: Enables [Auto Deploy](#auto-deploy)
with `master` branch directly deployed to production.
- **Continuous deployment to production using timed incremental rollout**: Sets the
[`INCREMENTAL_ROLLOUT_MODE`](#timed-incremental-rollout-to-production-premium) variable
to `timed`, and production deployment will be executed with a 5 minute delay between
each increment in rollout.
- **Automatic deployment to staging, manual deployment to production**: Sets the
[`STAGING_ENABLED`](#deploy-policy-for-staging-and-production-environments) and
[`INCREMENTAL_ROLLOUT_MODE`](#incremental-rollout-to-production-premium) variables
to `1` and `manual`. This means:
- `master` branch is directly deployed to staging.
- Manual actions are provided for incremental rollout to production.
## Using multiple Kubernetes clusters **(PREMIUM)**
@ -231,85 +338,6 @@ and verifying that your app is deployed as a review app in the Kubernetes
cluster with the `review/*` environment scope. Similarly, you can check the
other environments.
## Enabling/Disabling Auto DevOps
When first using Auto Devops, review the [requirements](#requirements) to ensure all necessary components to make
full use of Auto DevOps are available. If this is your fist time, we recommend you follow the
[quick start guide](quick_start_guide.md).
GitLab.com users can enable/disable Auto DevOps at the project-level only. Self-managed users
can enable/disable Auto DevOps at the project-level, group-level or instance-level.
### At the instance level (Administrators only)
Even when disabled at the instance level, group owners and project maintainers can still enable
Auto DevOps at the group and project level, respectively.
1. Go to **Admin area > Settings > Continuous Integration and Deployment**.
1. Toggle the checkbox labeled **Default to Auto DevOps pipeline for all projects**.
1. If enabling, optionally set up the Auto DevOps [base domain](#auto-devops-base-domain) which will be used for Auto Deploy and Auto Review Apps.
1. Click **Save changes** for the changes to take effect.
### At the group level
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/52447) in GitLab 11.10.
Only administrators and group owners can enable or disable Auto DevOps at the group level.
To enable or disable Auto DevOps at the group-level:
1. Go to group's **Settings > CI/CD > Auto DevOps** page.
1. Toggle the **Default to Auto DevOps pipeline** checkbox (checked to enable, unchecked to disable).
1. Click **Save changes** button for the changes to take effect.
When enabling or disabling Auto DevOps at group-level, group configuration will be implicitly used for
the subgroups and projects inside that group, unless Auto DevOps is specifically enabled or disabled on
the subgroup or project.
### At the project level
If enabling, check that your project doesn't have a `.gitlab-ci.yml`, or if one exists, remove it.
1. Go to your project's **Settings > CI/CD > Auto DevOps**.
1. Toggle the **Default to Auto DevOps pipeline** checkbox (checked to enable, unchecked to disable)
1. When enabling, it's optional but recommended to add in the [base domain](#auto-devops-base-domain)
that will be used by Auto DevOps to [deploy your application](#auto-deploy)
and choose the [deployment strategy](#deployment-strategy).
1. Click **Save changes** for the changes to take effect.
When the feature has been enabled, an Auto DevOps pipeline is triggered on the default branch.
### Enable for a percentage of projects
There is also a feature flag to enable Auto DevOps by default to your chosen percentage of projects.
This can be enabled from the console with the following, which uses the example of 10%:
`Feature.get(:force_autodevops_on_by_default).enable_percentage_of_actors(10)`
### Deployment strategy
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/38542) in GitLab 11.0.
You can change the deployment strategy used by Auto DevOps by going to your
project's **Settings > CI/CD > Auto DevOps**.
The available options are:
- **Continuous deployment to production**: Enables [Auto Deploy](#auto-deploy)
with `master` branch directly deployed to production.
- **Continuous deployment to production using timed incremental rollout**: Sets the
[`INCREMENTAL_ROLLOUT_MODE`](#timed-incremental-rollout-to-production-premium) variable
to `timed`, and production deployment will be executed with a 5 minute delay between
each increment in rollout.
- **Automatic deployment to staging, manual deployment to production**: Sets the
[`STAGING_ENABLED`](#deploy-policy-for-staging-and-production-environments) and
[`INCREMENTAL_ROLLOUT_MODE`](#incremental-rollout-to-production-premium) variables
to `1` and `manual`. This means:
- `master` branch is directly deployed to staging.
- Manual actions are provided for incremental rollout to production.
## Stages of Auto DevOps
The following sections describe the stages of Auto DevOps. Read them carefully
@ -672,8 +700,6 @@ workers:
### Auto Monitoring
See the [requirements](#requirements) for Auto Monitoring to enable this stage.
Once your application is deployed, Auto Monitoring makes it possible to monitor
your application's server and response metrics right out of the box. Auto
Monitoring uses [Prometheus](../../user/project/integrations/prometheus.md) to
@ -687,18 +713,15 @@ The metrics include:
- **Response Metrics:** latency, throughput, error rate
- **System Metrics:** CPU utilization, memory utilization
In order to make use of monitoring you need to:
To make use of Auto Monitoring:
1. [Deploy Prometheus](../../user/project/integrations/prometheus.md) into your Kubernetes cluster
1. If you would like response metrics, ensure you are running at least version
0.9.0 of NGINX Ingress and
[enable Prometheus metrics](https://github.com/kubernetes/ingress-nginx/blob/master/docs/examples/customization/custom-vts-metrics-prometheus/nginx-vts-metrics-conf.yaml).
1. Finally, [annotate](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/)
the NGINX Ingress deployment to be scraped by Prometheus using
`prometheus.io/scrape: "true"` and `prometheus.io/port: "10254"`.
To view the metrics, open the
[Monitoring dashboard for a deployed environment](../../ci/environments.md#monitoring-environments).
1. [Install and configure the requirements](#requirements).
1. [Enable Auto DevOps](#enablingdisabling-auto-devops) if you haven't done already.
1. Finally, go to your project's **CI/CD > Pipelines** and run a pipeline.
1. Once the pipeline finishes successfully, open the
[monitoring dashboard for a deployed environment](../../ci/environments.md#monitoring-environments)
to view the metrics of your deployed application. To view the metrics of the
whole Kubernetes cluster, navigate to **Operations > Metrics**.
![Auto Metrics](img/auto_monitoring.png)
@ -1303,7 +1326,6 @@ curl --data "value=true" --header "PRIVATE-TOKEN: personal_access_token" https:/
```
[ce-37115]: https://gitlab.com/gitlab-org/gitlab-foss/issues/37115
[kubernetes-clusters]: ../../user/project/clusters/index.md
[docker-in-docker]: ../../docker/using_docker_build.md#use-docker-in-docker-executor
[review-app]: ../../ci/review_apps/index.md
[container-registry]: ../../user/packages/container_registry/index.md

View File

@ -280,6 +280,6 @@ and customized to fit your workflow. Here are some helpful resources for further
1. [Multiple Kubernetes clusters](index.md#using-multiple-kubernetes-clusters-premium) **(PREMIUM)**
1. [Incremental rollout to production](index.md#incremental-rollout-to-production-premium) **(PREMIUM)**
1. [Disable jobs you don't need with environment variables](index.md#environment-variables)
1. [Use a static IP for your cluster](../../user/project/clusters/index.md#using-a-static-ip)
1. [Use a static IP for your cluster](../../user/clusters/applications.md#using-a-static-ip)
1. [Use your own buildpacks to build your application](index.md#custom-buildpacks)
1. [Prometheus monitoring](../../user/project/integrations/prometheus.md)

View File

@ -107,10 +107,20 @@ To resolve this:
project that is used to run your jobs and send the results back to
GitLab. It is used in conjunction with [GitLab
CI/CD](../../ci/README.md), the open-source continuous integration
service included with GitLab that coordinates the jobs. When installing
the GitLab Runner via the applications, it will run in **privileged
mode** by default. Make sure you read the [security
implications](../project/clusters/index.md#security-implications) before doing so.
service included with GitLab that coordinates the jobs.
If the project is on GitLab.com, shared Runners are available
(the first 2000 minutes are free, you can
[buy more later](../../subscriptions/index.md#extra-shared-runners-pipeline-minutes))
and you do not have to deploy one if they are enough for your needs. If a
project-specific Runner is desired, or there are no shared Runners, it is easy
to deploy one.
Note that the deployed Runner will be set as **privileged**, which means it will essentially
have root access to the underlying machine. This is required to build Docker images,
so it is the default. Make sure you read the
[security implications](../project/clusters/index.md#security-implications)
before deploying one.
NOTE: **Note:**
The [`runner/gitlab-runner`](https://gitlab.com/gitlab-org/charts/gitlab-runner)
@ -128,12 +138,113 @@ balancing, SSL termination, and name-based virtual hosting. It acts as a
web proxy for your applications and is useful if you want to use [Auto
DevOps](../../topics/autodevops/index.md) or deploy your own web apps.
NOTE: **Note:**
With the following procedure, a load balancer must be installed in your cluster
to obtain the endpoint. You can use either
Ingress, or Knative's own load balancer ([Istio](https://istio.io)) if using Knative.
In order to publish your web application, you first need to find the endpoint which will be either an IP
address or a hostname associated with your load balancer.
To install it, click on the **Install** button for Ingress. GitLab will attempt
to determine the external endpoint and it should be available within a few minutes.
#### Determining the external endpoint automatically
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/17052) in GitLab 10.6.
After you install Ingress, the external endpoint should be available within a few minutes.
TIP: **Tip:**
This endpoint can be used for the
[Auto DevOps base domain](../../topics/autodevops/index.md#auto-devops-base-domain)
using the `KUBE_INGRESS_BASE_DOMAIN` environment variable.
If the endpoint doesn't appear and your cluster runs on Google Kubernetes Engine:
1. Check your [Kubernetes cluster on Google Kubernetes Engine](https://console.cloud.google.com/kubernetes) to ensure there are no errors on its nodes.
1. Ensure you have enough [Quotas](https://console.cloud.google.com/iam-admin/quotas) on Google Kubernetes Engine. For more information, see [Resource Quotas](https://cloud.google.com/compute/quotas).
1. Check [Google Cloud's Status](https://status.cloud.google.com/) to ensure they are not having any disruptions.
Once installed, you may see a `?` for "Ingress IP Address" depending on the
cloud provider. For EKS specifically, this is because the ELB is created
with a DNS name, not an IP address. If GitLab is still unable to
determine the endpoint of your Ingress or Knative application, you can
[determine it manually](#determining-the-external-endpoint-manually).
NOTE: **Note:**
The [`stable/nginx-ingress`](https://github.com/helm/charts/tree/master/stable/nginx-ingress)
chart is used to install this application with a
[`values.yaml`](https://gitlab.com/gitlab-org/gitlab/blob/master/vendor/ingress/values.yaml)
file.
#### Determining the external endpoint manually
If the cluster is on GKE, click the **Google Kubernetes Engine** link in the
**Advanced settings**, or go directly to the
[Google Kubernetes Engine dashboard](https://console.cloud.google.com/kubernetes/)
and select the proper project and cluster. Then click **Connect** and execute
the `gcloud` command in a local terminal or using the **Cloud Shell**.
If the cluster is not on GKE, follow the specific instructions for your
Kubernetes provider to configure `kubectl` with the right credentials.
The output of the following examples will show the external endpoint of your
cluster. This information can then be used to set up DNS entries and forwarding
rules that allow external access to your deployed applications.
If you installed Ingress via the **Applications**, run the following command:
```bash
kubectl get service --namespace=gitlab-managed-apps ingress-nginx-ingress-controller -o jsonpath='{.status.loadBalancer.ingress[0].ip}'
```
Some Kubernetes clusters return a hostname instead, like [Amazon EKS](https://aws.amazon.com/eks/). For these platforms, run:
```bash
kubectl get service --namespace=gitlab-managed-apps ingress-nginx-ingress-controller -o jsonpath='{.status.loadBalancer.ingress[0].hostname}'
```
For Istio/Knative, the command will be different:
```bash
kubectl get svc --namespace=istio-system knative-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip} '
```
Otherwise, you can list the IP addresses of all load balancers:
```bash
kubectl get svc --all-namespaces -o jsonpath='{range.items[?(@.status.loadBalancer.ingress)]}{.status.loadBalancer.ingress[*].ip} '
```
NOTE: **Note:**
If EKS is used, an [Elastic Load Balancer](https://docs.aws.amazon.com/elasticloadbalancing/)
will also be created, which will incur additional AWS costs.
NOTE: **Note:**
You may see a trailing `%` on some Kubernetes versions, **do not include it**.
The Ingress is now available at this address and will route incoming requests to
the proper service based on the DNS name in the request. To support this, a
wildcard DNS CNAME record should be created for the desired domain name. For example,
`*.myekscluster.com` would point to the Ingress hostname obtained earlier.
#### Using a static IP
By default, an ephemeral external IP address is associated to the cluster's load
balancer. If you associate the ephemeral IP with your DNS and the IP changes,
your apps will not be able to be reached, and you'd have to change the DNS
record again. In order to avoid that, you should change it into a static
reserved IP.
Read how to [promote an ephemeral external IP address in GKE](https://cloud.google.com/compute/docs/ip-addresses/reserve-static-external-ip-address#promote_ephemeral_ip).
#### Pointing your DNS at the external endpoint
Once you've set up the external endpoint, you should associate it with a [wildcard DNS
record](https://en.wikipedia.org/wiki/Wildcard_DNS_record) such as `*.example.com.`
in order to be able to reach your apps. If your external endpoint is an IP address,
use an A record. If your external endpoint is a hostname, use a CNAME record.
#### Web Application Firewall (ModSecurity)
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/65192) in GitLab 12.3 (enabled using `ingress_modsecurity` [feature flag](../../development/feature_flags/development.md#enabling-a-feature-flag-in-development)).
@ -259,6 +370,14 @@ chart is used to install this application.
open-source monitoring and alerting system useful to supervise your
deployed applications.
GitLab is able to monitor applications automatically, using the
[Prometheus integration](../project/integrations/prometheus.md). Kubernetes container CPU and
memory metrics are automatically collected, and response metrics are retrieved
from NGINX Ingress as well.
To enable monitoring, simply install Prometheus into the cluster with the
**Install** button.
NOTE: **Note:**
The [`stable/prometheus`](https://github.com/helm/charts/tree/master/stable/prometheus)
chart is used to install this application with a

View File

@ -42,6 +42,9 @@ it is not possible due to a naming collision. For example:
| `gitlab-org/gitlab` | `@gitlab-org/gitlab` | Yes |
| `gitlab-org/gitlab` | `@foo/bar` | No |
CAUTION: **When updating the path of a user/group or transferring a (sub)group/project:**
If you update the root namespace of a project with NPM packages, your changes will be rejected. To be allowed to do that, make sure to remove any NPM package first. Don't forget to update your `.npmrc` files to follow the above naming convention and run `npm publish` if necessary.
Now, you can configure your project to authenticate with the GitLab NPM
Registry.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

View File

@ -218,149 +218,12 @@ differentiate the new cluster with the rest.
## Installing applications
GitLab can install and manage some applications in your project-level
cluster. For more information on installing, upgrading, uninstalling,
and troubleshooting applications for your project cluster, see
GitLab can install and manage some applications like Helm, GitLab Runner, Ingress,
Prometheus, etc., in your project-level cluster. For more information on
installing, upgrading, uninstalling, and troubleshooting applications for
your project cluster, see
[GitLab Managed Apps](../../clusters/applications.md).
### Getting the external endpoint
NOTE: **Note:**
With the following procedure, a load balancer must be installed in your cluster
to obtain the endpoint. You can use either
[Ingress](#installing-applications), or Knative's own load balancer
([Istio](https://istio.io)) if using [Knative](#installing-applications).
In order to publish your web application, you first need to find the endpoint which will be either an IP
address or a hostname associated with your load balancer.
#### Automatically determining the external endpoint
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/17052) in GitLab 10.6.
After you install [Ingress or Knative](#installing-applications), GitLab attempts to determine the external endpoint
and it should be available within a few minutes. If the endpoint doesn't appear
and your cluster runs on Google Kubernetes Engine:
1. Check your [Kubernetes cluster on Google Kubernetes Engine](https://console.cloud.google.com/kubernetes) to ensure there are no errors on its nodes.
1. Ensure you have enough [Quotas](https://console.cloud.google.com/iam-admin/quotas) on Google Kubernetes Engine. For more information, see [Resource Quotas](https://cloud.google.com/compute/quotas).
1. Check [Google Cloud's Status](https://status.cloud.google.com/) to ensure they are not having any disruptions.
If GitLab is still unable to determine the endpoint of your Ingress or Knative application, you can
manually determine it by following the steps below.
#### Manually determining the external endpoint
If the cluster is on GKE, click the **Google Kubernetes Engine** link in the
**Advanced settings**, or go directly to the
[Google Kubernetes Engine dashboard](https://console.cloud.google.com/kubernetes/)
and select the proper project and cluster. Then click **Connect** and execute
the `gcloud` command in a local terminal or using the **Cloud Shell**.
If the cluster is not on GKE, follow the specific instructions for your
Kubernetes provider to configure `kubectl` with the right credentials.
The output of the following examples will show the external endpoint of your
cluster. This information can then be used to set up DNS entries and forwarding
rules that allow external access to your deployed applications.
If you installed the Ingress [via the **Applications**](#installing-applications),
run the following command:
```bash
kubectl get service --namespace=gitlab-managed-apps ingress-nginx-ingress-controller -o jsonpath='{.status.loadBalancer.ingress[0].ip}'
```
Some Kubernetes clusters return a hostname instead, like [Amazon EKS](https://aws.amazon.com/eks/). For these platforms, run:
```bash
kubectl get service --namespace=gitlab-managed-apps ingress-nginx-ingress-controller -o jsonpath='{.status.loadBalancer.ingress[0].hostname}'
```
For Istio/Knative, the command will be different:
```bash
kubectl get svc --namespace=istio-system knative-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip} '
```
Otherwise, you can list the IP addresses of all load balancers:
```bash
kubectl get svc --all-namespaces -o jsonpath='{range.items[?(@.status.loadBalancer.ingress)]}{.status.loadBalancer.ingress[*].ip} '
```
#### Using a static IP
By default, an ephemeral external IP address is associated to the cluster's load
balancer. If you associate the ephemeral IP with your DNS and the IP changes,
your apps will not be able to be reached, and you'd have to change the DNS
record again. In order to avoid that, you should change it into a static
reserved IP.
Read how to [promote an ephemeral external IP address in GKE](https://cloud.google.com/compute/docs/ip-addresses/reserve-static-external-ip-address#promote_ephemeral_ip).
#### Pointing your DNS at the external endpoint
Once you've set up the external endpoint, you should associate it with a [wildcard DNS
record](https://en.wikipedia.org/wiki/Wildcard_DNS_record) such as `*.example.com.`
in order to be able to reach your apps. If your external endpoint is an IP address,
use an A record. If your external endpoint is a hostname, use a CNAME record.
#### Deploy services to the cluster
GitLab supports one-click deployment of helpful services to the cluster, many of
which support Auto DevOps. Back on the Kubernetes cluster screen in GitLab, a
list of applications is now available to deploy.
First, install Helm Tiller, a package manager for Kubernetes. This enables
deployment of the other applications.
![Deploy Apps](img/deploy_apps.png)
##### Deploying NGINX Ingress (optional)
Next, if you would like the deployed app to be reachable on the internet, deploy
the Ingress. Note that this will also cause an
[Elastic Load Balancer](https://docs.aws.amazon.com/elasticloadbalancing/)
to be created, which will incur additional AWS costs.
Once installed, you may see a `?` for "Ingress IP Address". This is because the
created ELB is available at a DNS name, not an IP address. To get the DNS name,
run:
```sh
kubectl get service ingress-nginx-ingress-controller -n gitlab-managed-apps -o jsonpath="{.status.loadBalancer.ingress[0].hostname}"
```
Note that you may see a trailing `%` on some Kubernetes versions, **do not include it**.
The Ingress is now available at this address and will route incoming requests to
the proper service based on the DNS name in the request. To support this, a
wildcard DNS CNAME record should be created for the desired domain name. For example,
`*.myekscluster.com` would point to the Ingress hostname obtained earlier.
![Create DNS](img/create_dns.png)
##### Deploying the GitLab Runner (optional)
If the project is on GitLab.com, free shared Runners are available and you do
not have to deploy one. If a project specific Runner is desired, or there are no
shared Runners, it is easy to deploy one.
Simply click on the **Install** button for the GitLab Runner. It is important to
note that the Runner deployed is set as **privileged**, which means it essentially
has root access to the underlying machine. This is required to build docker images,
and so is on by default.
##### Deploying Prometheus (optional)
GitLab is able to monitor applications automatically, utilizing
[Prometheus](../integrations/prometheus.html). Kubernetes container CPU and
memory metrics are automatically collected, and response metrics are retrieved
from NGINX Ingress as well.
To enable monitoring, simply install Prometheus into the cluster with the
**Install** button.
## Deploying to a Kubernetes cluster
A Kubernetes cluster can be the destination for a deployment job. If

View File

@ -77,7 +77,7 @@ The minimum recommended cluster size to run Knative is 3-nodes, 6 vCPUs, and 22.
![install-knative](img/install-knative.png)
1. After the Knative installation has finished, you can wait for the IP address or hostname to be displayed in the
**Knative Endpoint** field or [retrieve the Istio Ingress Endpoint manually](../#manually-determining-the-external-endpoint).
**Knative Endpoint** field or [retrieve the Istio Ingress Endpoint manually](../../../clusters/applications.md#determining-the-external-endpoint-manually).
NOTE: **Note:**
Running `kubectl` commands on your cluster requires setting up access to the cluster first.

View File

@ -30,7 +30,7 @@ For other deployments, there is [some configuration](#manually-setting-up-nginx-
### About managed NGINX Ingress deployments
NGINX Ingress is deployed into the `gitlab-managed-apps` namespace, using the [official Helm chart](https://github.com/helm/charts/tree/master/stable/nginx-ingress). NGINX Ingress will be [externally reachable via the Load Balancer's Endpoint](../../clusters/index.md#getting-the-external-endpoint).
NGINX Ingress is deployed into the `gitlab-managed-apps` namespace, using the [official Helm chart](https://github.com/helm/charts/tree/master/stable/nginx-ingress). NGINX Ingress will be [externally reachable via the Load Balancer's Endpoint](../../../clusters/applications.md#ingress).
NGINX is configured for Prometheus monitoring, by setting:

View File

@ -30,7 +30,7 @@ For other deployments, there is [some configuration](#manually-setting-up-nginx-
### About managed NGINX Ingress deployments
NGINX Ingress is deployed into the `gitlab-managed-apps` namespace, using the [official Helm chart](https://github.com/helm/charts/tree/master/stable/nginx-ingress). NGINX Ingress will be [externally reachable via the Load Balancer's Endpoint](../../clusters/index.md#getting-the-external-endpoint).
NGINX Ingress is deployed into the `gitlab-managed-apps` namespace, using the [official Helm chart](https://github.com/helm/charts/tree/master/stable/nginx-ingress). NGINX Ingress will be [externally reachable via the Load Balancer's Endpoint](../../../clusters/applications.md#ingress).
NGINX is configured for Prometheus monitoring, by setting:

View File

@ -0,0 +1,61 @@
---
type: reference, howto
---
# New Pages website from a forked sample
To get started with GitLab Pages from a sample website, the easiest
way to do it is by using one of the [bundled templates](pages_bundled_template.md).
If you don't find one that suits your needs, you can opt by
forking (copying) a [sample project from the most popular Static Site Generators](https://gitlab.com/pages).
<table class="borderless-table center fixed-table middle width-80">
<tr>
<td style="width: 30%"><img src="../img/icons/fork.png" alt="Fork" class="image-noshadow half-width"></td>
<td style="width: 10%">
<strong>
<i class="fa fa-angle-double-right" aria-hidden="true"></i>
</strong>
</td>
<td style="width: 30%"><img src="../img/icons/terminal.png" alt="Deploy" class="image-noshadow half-width"></td>
<td style="width: 10%">
<strong>
<i class="fa fa-angle-double-right" aria-hidden="true"></i>
</strong>
</td>
<td style="width: 30%"><img src="../img/icons/click.png" alt="Visit" class="image-noshadow half-width"></td>
</tr>
<tr>
<td><em>Fork an example project</em></td>
<td></td>
<td><em>Deploy your website</em></td>
<td></td>
<td><em>Visit your website's URL</em></td>
</tr>
</table>
**<i class="fa fa-youtube-play youtube" aria-hidden="true"></i> Watch a [video tutorial](https://www.youtube.com/watch?v=TWqh9MtT4Bg) with all the steps below.**
1. [Fork](../../../../gitlab-basics/fork-project.md) a sample project from the [GitLab Pages examples](https://gitlab.com/pages) group.
1. From the left sidebar, navigate to your project's **CI/CD > Pipelines**
and click **Run pipeline** to trigger GitLab CI/CD to build and deploy your
site to the server.
1. Once the pipeline has finished successfully, find the link to visit your
website from your project's **Settings > Pages**. It can take aproximatelly
30 minutes to be deployed.
You can also take some **optional** further steps:
- _Remove the fork relationship._ The fork relationship is necessary to contribute back to the project you originally forked from. If you don't have any intentions to do so, you can remove it. To do so, navigate to your project's **Settings**, expand **Advanced settings**, and scroll down to **Remove fork relationship**:
![remove fork relationship](../img/remove_fork_relationship.png)
- _Make it a user or group website._ To turn a **project website** forked
from the Pages group into a **user/group** website, you'll need to:
- Rename it to `namespace.gitlab.io`: go to your project's
**Settings > General** and expand **Advanced**. Scroll down to
**Rename repository** and change the path to `namespace.gitlab.io`.
- Adjust your SSG's [base URL](../getting_started_part_one.md#urls-and-baseurls) from `"project-name"` to
`""`. This setting will be at a different place for each SSG, as each of them
have their own structure and file tree. Most likely, it will be in the SSG's
config file.

View File

@ -0,0 +1,45 @@
---
type: reference, howto
---
# Start a new Pages website from scratch or deploy an exising website
If you already have a website and want to deploy it with GitLab Pages,
or, if you want to start a new site from scratch, you'll need to:
- Create a new project in GitLab to hold your site content.
- Set up GitLab CI/CD to deploy your website to Pages.
To do so, follow the steps below.
1. From your **Project**'s **[Dashboard](https://gitlab.com/dashboard/projects)**,
click **New project**, and name it according to the
[Pages domain names](../getting_started_part_one.md#gitlab-pages-domain-names).
1. Clone it to your local computer, add your website
files to your project, add, commit and push to GitLab.
Alternativelly, you can run `git init` in your local directory,
add the remote URL:
`git remote add origin git@gitlab.com:namespace/project-name.git`,
then add, commit, and push to GitLab.
1. From the your **Project**'s page, click **Set up CI/CD**:
![setup GitLab CI/CD](../img/setup_ci.png)
1. Choose one of the templates from the dropbox menu.
Pick up the template corresponding to the SSG you're using (or plain HTML).
![gitlab-ci templates](../img/choose_ci_template.png)
Note that, if you don't find a corresponding template, you can look into
[GitLab Pages group of sample projects](https://gitlab.com/pages),
you may find one among them that suits your needs, from which you
can copy `.gitlab-ci.yml`'s content and adjust for your case.
If you don't find it there either, [learn how to write a `.gitlab-ci.yml`
file for GitLab Pages](../getting_started_part_four.md).
Once you have both site files and `.gitlab-ci.yml` in your project's
root, GitLab CI/CD will build your site and deploy it with Pages.
Once the first build passes, you access your site by
navigating to your **Project**'s **Settings** > **Pages**,
where you'll find its default URL. It can take approximately 30 min to be
deployed.

View File

@ -0,0 +1,29 @@
---
type: reference, howto
---
# New Pages website from a bundled template
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/47857)
in GitLab 11.8.
The simplest way to create a GitLab Pages site is to use one of the most
popular templates, which come already bundled with GitLab and are ready to go.
1. From the top navigation, click the **+** button and select **New project**.
1. Select **Create from Template**.
1. Choose one of the templates starting with **Pages**:
![Project templates for Pages](../img/pages_project_templates_v11_8.png)
1. From the left sidebar, navigate to your project's **CI/CD > Pipelines**
and click **Run pipeline** to trigger GitLab CI/CD to build and deploy your
site to the server.
1. After the pipeline has finished successfully, wait approximately 30 minutes
for your website to be visible. After waiting 30 minutes, find the link to
visit your website from your project's **Settings > Pages**. If the link
leads to a 404 page, wait a few minutes and try again.
Your website is then visible on your domain and you can modify your files
as you wish. For every modification pushed to your repository, GitLab CI/CD
will run a new pipeline to immediately publish your changes to the server.

View File

@ -3,24 +3,11 @@ last_updated: 2018-06-04
type: concepts, reference
---
# Static sites and GitLab Pages domains
# GitLab Pages domain names, URLs, and baseurls
On this document, learn how to name your project for GitLab Pages
according to your intended website's URL.
## Static sites
GitLab Pages only supports static websites, meaning,
your output files must be HTML, CSS, and JavaScript only.
To create your static site, you can either hardcode in HTML,
CSS, and JS, or use a [Static Site Generator (SSG)](https://www.staticgen.com/)
to simplify your code and build the static site for you,
which is highly recommendable and much faster than hardcoding.
See the [further reading](#further-reading) section below for
references on static site concepts.
## GitLab Pages domain names
>**Note:**
@ -93,11 +80,35 @@ To understand Pages domains clearly, read the examples below.
- On your GitLab instance, replace `gitlab.io` above with your
Pages server domain. Ask your sysadmin for this information.
_Read on about [Projects for GitLab Pages and URL structure](getting_started_part_two.md)._
## URLs and Baseurls
### Further reading
Every Static Site Generator (SSG) default configuration expects
to find your website under a (sub)domain (`example.com`), not
in a subdirectory of that domain (`example.com/subdir`). Therefore,
whenever you publish a project website (`namespace.gitlab.io/project-name`),
you'll have to look for this configuration (base URL) on your SSG's
documentation and set it up to reflect this pattern.
- Read through this technical overview on [Static versus Dynamic Websites](https://about.gitlab.com/blog/2016/06/03/ssg-overview-gitlab-pages-part-1-dynamic-x-static/)
- Understand [how modern Static Site Generators work](https://about.gitlab.com/blog/2016/06/10/ssg-overview-gitlab-pages-part-2/) and what you can add to your static site
- You can use [any SSG with GitLab Pages](https://about.gitlab.com/blog/2016/06/17/ssg-overview-gitlab-pages-part-3-examples-ci/)
- Fork an [example project](https://gitlab.com/pages) to build your website based upon
For example, for a Jekyll site, the `baseurl` is defined in the Jekyll
configuration file, `_config.yml`. If your website URL is
`https://john.gitlab.io/blog/`, you need to add this line to `_config.yml`:
```yaml
baseurl: "/blog"
```
On the contrary, if you deploy your website after forking one of
our [default examples](https://gitlab.com/pages), the baseurl will
already be configured this way, as all examples there are project
websites. If you decide to make yours a user or group website, you'll
have to remove this configuration from your project. For the Jekyll
example we've just mentioned, you'd have to change Jekyll's `_config.yml` to:
```yaml
baseurl: ""
```
## Custom Domains
GitLab Pages supports custom domains and subdomains, served under HTTP or HTTPS.
See [GitLab Pages custom domains and SSL/TLS Certificates](custom_domains_ssl_tls_certification/index.md) for more information.

View File

@ -1,172 +1,5 @@
---
last_updated: 2019-06-04
type: reference, howto
redirect_to: 'index.md'
---
# Projects for GitLab Pages and URL structure
## What you need to get started
To get started with GitLab Pages, you need:
1. A project, thus a repository to hold your website's codebase.
1. A configuration file (`.gitlab-ci.yml`) to deploy your site.
1. A specific `job` called `pages` in the configuration file
that will make GitLab aware that you are deploying a GitLab Pages website.
1. A `public` directory with the static content of the website.
Optional Features:
1. A custom domain or subdomain.
1. A DNS pointing your (sub)domain to your Pages site.
1. **Optional**: an SSL/TLS certificate so your custom
domain is accessible under HTTPS.
The optional settings, custom domain, DNS records, and SSL/TLS certificates, are described in [GitLab Pages custom domains and SSL/TLS Certificates](custom_domains_ssl_tls_certification/index.md)).
## Project
Your GitLab Pages project is a regular project created the
same way you do for the other ones. To get started with GitLab Pages, you have three ways:
- [Use one of the popular project templates bundled with GitLab](#use-one-of-the-popular-pages-templates-bundled-with-gitlab).
- [Fork one of the templates from Page Examples](#fork-a-project-to-get-started-from).
- [Create a new project from scratch](#create-a-project-from-scratch).
### Use one of the popular Pages templates bundled with GitLab
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/47857)
in GitLab 11.8.
The simplest way to create a GitLab Pages site is to
[use one of the most popular templates](index.md#getting-started),
which come already bundled with GitLab and are ready to go.
### Fork a project to get started from
If you don't find an existing project template that suits you,
we've created this [group](https://gitlab.com/pages) of default projects
containing the most popular SSGs templates to get you started.
<table class="borderless-table center fixed-table middle width-80">
<tr>
<td style="width: 30%"><img src="img/icons/fork.png" alt="Fork" class="image-noshadow half-width"></td>
<td style="width: 10%">
<strong>
<i class="fa fa-angle-double-right" aria-hidden="true"></i>
</strong>
</td>
<td style="width: 30%"><img src="img/icons/terminal.png" alt="Deploy" class="image-noshadow half-width"></td>
<td style="width: 10%">
<strong>
<i class="fa fa-angle-double-right" aria-hidden="true"></i>
</strong>
</td>
<td style="width: 30%"><img src="img/icons/click.png" alt="Visit" class="image-noshadow half-width"></td>
</tr>
<tr>
<td><em>Fork an example project</em></td>
<td></td>
<td><em>Deploy your website</em></td>
<td></td>
<td><em>Visit your website's URL</em></td>
</tr>
</table>
**<i class="fa fa-youtube-play youtube" aria-hidden="true"></i> Watch a [video tutorial](https://www.youtube.com/watch?v=TWqh9MtT4Bg) with all the steps below.**
1. [Fork](../../../gitlab-basics/fork-project.md) a sample project from the [GitLab Pages examples](https://gitlab.com/pages) group.
1. From the left sidebar, navigate to your project's **CI/CD > Pipelines**
and click **Run pipeline** to trigger GitLab CI/CD to build and deploy your
site to the server.
1. Once the pipeline has finished successfully, find the link to visit your
website from your project's **Settings > Pages**.
You can also take some **optional** further steps:
- _Remove the fork relationship._ The fork relationship is necessary to contribute back to the project you originally forked from. If you don't have any intentions to do so, you can remove it. To do so, navigate to your project's **Settings**, expand **Advanced settings**, and scroll down to **Remove fork relationship**:
![remove fork relationship](img/remove_fork_relationship.png)
- _Make it a user or group website._ To turn a **project website** forked
from the Pages group into a **user/group** website, you'll need to:
- Rename it to `namespace.gitlab.io`: go to your project's
**Settings > General** and expand **Advanced**. Scroll down to
**Rename repository** and change the path to `namespace.gitlab.io`.
- Adjust your SSG's [base URL](#urls-and-baseurls) from `"project-name"` to
`""`. This setting will be at a different place for each SSG, as each of them
have their own structure and file tree. Most likely, it will be in the SSG's
config file.
### Create a project from scratch
1. From your **Project**'s **[Dashboard](https://gitlab.com/dashboard/projects)**,
click **New project**, and name it according to the
[Pages domain names](getting_started_part_one.md#gitlab-pages-domain-names).
1. Clone it to your local computer, add your website
files to your project, add, commit and push to GitLab.
1. From the your **Project**'s page, click **Set up CI/CD**:
![setup GitLab CI/CD](img/setup_ci.png)
1. Choose one of the templates from the dropbox menu.
Pick up the template corresponding to the SSG you're using (or plain HTML).
![gitlab-ci templates](img/choose_ci_template.png)
Once you have both site files and `.gitlab-ci.yml` in your project's
root, GitLab CI/CD will build your site and deploy it with Pages.
Once the first build passes, you see your site is live by
navigating to your **Project**'s **Settings** > **Pages**,
where you'll find its default URL.
> **Notes:**
>
> - GitLab Pages [supports any SSG](https://about.gitlab.com/blog/2016/06/17/ssg-overview-gitlab-pages-part-3-examples-ci/), but,
> if you don't find yours among the templates, you'll need
> to configure your own `.gitlab-ci.yml`. To do that, please
> read through the article [Creating and Tweaking GitLab CI/CD for GitLab Pages](getting_started_part_four.md). New SSGs are very welcome among
> the [example projects](https://gitlab.com/pages). If you set
> up a new one, please
> [contribute](https://gitlab.com/pages/pages.gitlab.io/blob/master/CONTRIBUTING.md)
> to our examples.
>
> - The second step _"Clone it to your local computer"_, can be done
> differently, achieving the same results: instead of cloning the bare
> repository to you local computer and moving your site files into it,
> you can run `git init` in your local website directory, add the
> remote URL: `git remote add origin git@gitlab.com:namespace/project-name.git`,
> then add, commit, and push to GitLab.
## URLs and Baseurls
Every Static Site Generator (SSG) default configuration expects
to find your website under a (sub)domain (`example.com`), not
in a subdirectory of that domain (`example.com/subdir`). Therefore,
whenever you publish a project website (`namespace.gitlab.io/project-name`),
you'll have to look for this configuration (base URL) on your SSG's
documentation and set it up to reflect this pattern.
For example, for a Jekyll site, the `baseurl` is defined in the Jekyll
configuration file, `_config.yml`. If your website URL is
`https://john.gitlab.io/blog/`, you need to add this line to `_config.yml`:
```yaml
baseurl: "/blog"
```
On the contrary, if you deploy your website after forking one of
our [default examples](https://gitlab.com/pages), the baseurl will
already be configured this way, as all examples there are project
websites. If you decide to make yours a user or group website, you'll
have to remove this configuration from your project. For the Jekyll
example we've just mentioned, you'd have to change Jekyll's `_config.yml` to:
```yaml
baseurl: ""
```
## Custom Domains
GitLab Pages supports custom domains and subdomains, served under HTTP or HTTPS.
See [GitLab Pages custom domains and SSL/TLS Certificates](custom_domains_ssl_tls_certification/index.md) for more information.
This document was moved to [another location](index.md#getting-started).

View File

@ -73,6 +73,7 @@ publish any website written directly in plain HTML, CSS, and JavaScript.</p>
To use GitLab Pages, first you need to create a project in GitLab to upload your website's
files to. These projects can be either public, internal, or private, at your own choice.
GitLab will always deploy your website from a very specific folder called `public` in your
repository. Note that when you create a new project in GitLab, a [repository](../repository/index.md)
becomes available automatically.
@ -80,67 +81,48 @@ becomes available automatically.
To deploy your site, GitLab will use its built-in tool called [GitLab CI/CD](../../../ci/README.md),
to build your site and publish it to the GitLab Pages server. The sequence of
scripts that GitLab CI/CD runs to accomplish this task is created from a file named
`.gitlab-ci.yml`, which you can [create and modify](getting_started_part_four.md) at will.
`.gitlab-ci.yml`, which you can [create and modify](getting_started_part_four.md) at will. A specific `job` called `pages` in the configuration file will make GitLab aware that you are deploying a GitLab Pages website.
You can either use GitLab's [default domain for GitLab Pages websites](getting_started_part_one.md#gitlab-pages-domain-names),
`*.gitlab.io`, or your own domain (`example.com`). In that case, you'll
need admin access to your domain's registrar (or control panel) to set it up with Pages.
Optionally, when adding your own domain, you can add an SSL/TLS certificate to secure your
site under the HTTPS protocol.
### Getting started
To get started with GitLab Pages, you can either:
- [Create a project from scratch](getting_started_part_two.md#create-a-project-from-scratch).
- [Copy an existing example project](getting_started_part_two.md#fork-a-project-to-get-started-from).
- Use a bundled project template ready to go:
- [Use a bundled website template ready to go](getting_started/pages_bundled_template.md).
- [Copy an existing sample](getting_started/fork_sample_project.md).
- [Create a website from scratch or deploy an existing one](getting_started/new_or_existing_website.md).
1. From the top navigation, click the **+** button and select **New project**.
1. Select **Create from Template**.
1. Choose one of the templates starting with **Pages**:
Optional features:
![Project templates for Pages](img/pages_project_templates_v11_8.png)
1. From the left sidebar, navigate to your project's **CI/CD > Pipelines**
and click **Run pipeline** to trigger GitLab CI/CD to build and deploy your
site to the server.
1. After the pipeline has finished successfully, wait approximately 30 minutes
for your website to be visible. After waiting 30 minutes, find the link to
visit your website from your project's **Settings > Pages**. If the link
leads to a 404 page, wait a few minutes and try again.
Your website is then visible on your domain and you can modify your files
as you wish. For every modification pushed to your repository, GitLab CI/CD
will run a new pipeline to immediately publish your changes to the server.
_Advanced options:_
- [Use a custom domain](custom_domains_ssl_tls_certification/index.md#set-up-pages-with-a-custom-domain)
- Apply [SSL/TLS certification](custom_domains_ssl_tls_certification/index.md#adding-an-ssltls-certificate-to-pages) to your custom domain
## Availability
If you're using GitLab.com, your website will be publicly available to the internet.
If you're using self-managed instances (Core, Starter, Premium, or Ultimate),
your websites will be published on your own server, according to the
[Pages admin settings](../../../administration/pages/index.md) chosen by your sysadmin,
who can opt for making them public or internal to your server.
- Use a [custom domain or subdomain](custom_domains_ssl_tls_certification/index.md#set-up-pages-with-a-custom-domain).
- Add an [SSL/TLS certificate to secure your site under the HTTPS protocol](custom_domains_ssl_tls_certification/index.md#adding-an-ssltls-certificate-to-pages).
Note that, if you're using GitLab Pages default domain (`.gitlab.io`),
your website will be automatically secure and available under
HTTPS. If you're using your own custom domain, you can
optionally secure it with SSL/TLS certificates.
## Availability
If you're using GitLab.com, your website will be publicly available to the internet.
To restrict access to your website, enable [GitLab Pages Access Control](pages_access_control.md).
If you're using self-managed instances (Core, Starter, Premium, or Ultimate),
your websites will be published on your own server, according to the
[Pages admin settings](../../../administration/pages/index.md) chosen by your sysadmin,
who can opt for making them public or internal to your server.
## Explore GitLab Pages
To learn more about configuration options for GitLab Pages, read the following:
| Document | Description |
| --- | --- |
| [Static websites and Pages domains](getting_started_part_one.md) | Understand what is a static website, and how GitLab Pages default domains work. |
| [Projects and URL structure](getting_started_part_two.md) | Forking projects and creating new ones from scratch, understanding URLs structure and baseurls. |
| [GitLab Pages domain names, URLs, and baseurls](getting_started_part_one.md) | Understand how GitLab Pages default domains work. |
| [GitLab CI/CD for GitLab Pages](getting_started_part_four.md) | Understand how to create your own `.gitlab-ci.yml` for your site. |
| [Exploring GitLab Pages](introduction.md) | Requirements, technical aspects, specific GitLab CI's configuration options, Access Control, custom 404 pages, limitations, FAQ. |
|---+---|

View File

@ -69,40 +69,7 @@ don't have to create and edit HTML files manually. For example, Jekyll has the
## GitLab Pages Access Control **(CORE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/33422) in GitLab 11.5.
You can enable Pages access control on your project, so that only
[members of your project](../../permissions.md#project-members-permissions)
(at least Guest) can access your website:
1. Navigate to your project's **Settings > General > Permissions**.
1. Toggle the **Pages** button to enable the access control.
NOTE: **Note:**
If you don't see the toggle button, that means that it's not enabled.
Ask your administrator to [enable it](../../../administration/pages/index.md#access-control).
1. The Pages access control dropdown allows you to set who can view pages hosted
with GitLab Pages, depending on your project's visibility:
- If your project is private:
- **Only project members**: Only project members will be able to browse the website.
- **Everyone**: Everyone, both logged into and logged out of GitLab, will be able to browse the website, no matter their project membership.
- If your project is internal:
- **Only project members**: Only project members will be able to browse the website.
- **Everyone with access**: Everyone logged into GitLab will be able to browse the website, no matter their project membership.
- **Everyone**: Everyone, both logged into and logged out of GitLab, will be able to browse the website, no matter their project membership.
- If your project is public:
- **Only project members**: Only project members will be able to browse the website.
- **Everyone with access**: Everyone, both logged into and logged out of GitLab, will be able to browse the website, no matter their project membership.
1. Click **Save changes**.
---
The next time someone tries to access your website and the access control is
enabled, they will be presented with a page to sign into GitLab and verify they
can access the website.
To restrict access to your website, enable [GitLab Pages Access Control](pages_access_control.md).
## Unpublishing your Pages

View File

@ -21,8 +21,8 @@ open source Certificate Authority.
To follow along with this tutorial, we assume you already have:
- Created a [project](getting_started_part_two.md) in GitLab which
contains your website's source code.
- [Created a project](index.md#getting-started) in GitLab
containing your website's source code.
- Acquired a domain (`example.com`) and added a [DNS entry](custom_domains_ssl_tls_certification/index.md#set-up-pages-with-a-custom-domain)
pointing it to your Pages website.
- [Added your domain to your Pages project](custom_domains_ssl_tls_certification/index.md#steps)

View File

@ -0,0 +1,48 @@
---
type: reference, howto
---
# GitLab Pages Access Control
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/33422) in GitLab 11.5.
> - Available on GitLab.com in GitLab 12.4.
You can enable Pages access control on your project, so that only
[members of your project](../../permissions.md#project-members-permissions)
(at least Guest) can access your website:
1. Navigate to your project's **Settings > General > Permissions**.
1. Toggle the **Pages** button to enable the access control.
NOTE: **Note:**
If you don't see the toggle button, that means that it's not enabled.
Ask your administrator to [enable it](../../../administration/pages/index.md#access-control).
1. The Pages access control dropdown allows you to set who can view pages hosted
with GitLab Pages, depending on your project's visibility:
- If your project is private:
- **Only project members**: Only project members will be able to browse the website.
- **Everyone**: Everyone, both logged into and logged out of GitLab, will be able to browse the website, no matter their project membership.
- If your project is internal:
- **Only project members**: Only project members will be able to browse the website.
- **Everyone with access**: Everyone logged into GitLab will be able to browse the website, no matter their project membership.
- **Everyone**: Everyone, both logged into and logged out of GitLab, will be able to browse the website, no matter their project membership.
- If your project is public:
- **Only project members**: Only project members will be able to browse the website.
- **Everyone with access**: Everyone, both logged into and logged out of GitLab, will be able to browse the website, no matter their project membership.
1. Click **Save changes**.
The next time someone tries to access your website and the access control is
enabled, they will be presented with a page to sign into GitLab and verify they
can access the website.
## Terminating a Pages session
If you want to log out from your Pages website,
you can do so by revoking application access token for GitLab Pages:
1. Navigate to your profile's **Settings > Applications**.
1. Find **Authorized applications** at the bottom of the page.
1. Find **GitLab Pages** and press the **Revoke** button.

View File

@ -0,0 +1,78 @@
# frozen_string_literal: true
module Banzai
module Filter
# HTML filter that inserts a placeholder element for each
# reference to a grafana dashboard.
class InlineGrafanaMetricsFilter < Banzai::Filter::InlineEmbedsFilter
# Placeholder element for the frontend to use as an
# injection point for charts.
def create_element(params)
begin_loading_dashboard(params[:url])
doc.document.create_element(
'div',
class: 'js-render-metrics',
'data-dashboard-url': metrics_dashboard_url(params)
)
end
def embed_params(node)
return unless Feature.enabled?(:gfm_grafana_integration)
query_params = Gitlab::Metrics::Dashboard::Url.parse_query(node['href'])
return unless [:panelId, :from, :to].all? do |param|
query_params.include?(param)
end
{ url: node['href'], start: query_params[:from], end: query_params[:to] }
end
# Selects any links with an href contains the configured
# grafana domain for the project
def xpath_search
return unless grafana_url.present?
%(descendant-or-self::a[starts-with(@href, '#{grafana_url}')])
end
private
def project
context[:project]
end
def grafana_url
project&.grafana_integration&.grafana_url
end
def metrics_dashboard_url(params)
Gitlab::Routing.url_helpers.project_grafana_api_metrics_dashboard_url(
project,
embedded: true,
grafana_url: params[:url],
start: format_time(params[:start]),
end: format_time(params[:end])
)
end
# Formats a timestamp from Grafana for compatibility with
# parsing in JS via `new Date(timestamp)`
#
# @param time [String] Represents miliseconds since epoch
def format_time(time)
Time.at(time.to_i / 1000).utc.strftime('%FT%TZ')
end
# Fetches a dashboard and caches the result for the
# FE to fetch quickly while rendering charts
def begin_loading_dashboard(url)
::Gitlab::Metrics::Dashboard::Finder.find(
project,
embedded: true,
grafana_url: url
)
end
end
end
end

View File

@ -8,14 +8,17 @@ module Banzai
include Gitlab::Utils::StrongMemoize
METRICS_CSS_CLASS = '.js-render-metrics'
URL = Gitlab::Metrics::Dashboard::Url
Embed = Struct.new(:project_path, :permission)
# Finds all embeds based on the css class the FE
# uses to identify the embedded content, removing
# only unnecessary nodes.
def call
nodes.each do |node|
path = paths_by_node[node]
user_has_access = user_access_by_path[path]
embed = embeds_by_node[node]
user_has_access = user_access_by_embed[embed]
node.remove unless user_has_access
end
@ -30,40 +33,69 @@ module Banzai
end
# Returns all nodes which the FE will identify as
# a metrics dashboard placeholder element
# a metrics embed placeholder element
#
# @return [Nokogiri::XML::NodeSet]
def nodes
@nodes ||= doc.css(METRICS_CSS_CLASS)
end
# Maps a node to the full path of a project.
# Maps a node to key properties of an embed.
# Memoized so we only need to run the regex to get
# the project full path from the url once per node.
#
# @return [Hash<Nokogiri::XML::Node, String>]
def paths_by_node
strong_memoize(:paths_by_node) do
nodes.each_with_object({}) do |node, paths|
paths[node] = path_for_node(node)
# @return [Hash<Nokogiri::XML::Node, Embed>]
def embeds_by_node
strong_memoize(:embeds_by_node) do
nodes.each_with_object({}) do |node, embeds|
embed = Embed.new
url = node.attribute('data-dashboard-url').to_s
set_path_and_permission(embed, url, URL.regex, :read_environment)
set_path_and_permission(embed, url, URL.grafana_regex, :read_project) unless embed.permission
embeds[node] = embed if embed.permission
end
end
end
# Gets a project's full_path from the dashboard url
# in the placeholder node. The FE will use the attr
# `data-dashboard-url`, so we want to check against that
# attribute directly in case a user has manually
# created a metrics element (rather than supporting
# an alternate attr in InlineMetricsFilter).
# Attempts to determine the path and permission attributes
# of a url based on expected dashboard url formats and
# sets the attributes on an Embed object
#
# @return [String]
def path_for_node(node)
url = node.attribute('data-dashboard-url').to_s
Gitlab::Metrics::Dashboard::Url.regex.match(url) do |m|
# @param embed [Embed]
# @param url [String]
# @param regex [RegExp]
# @param permission [Symbol]
def set_path_and_permission(embed, url, regex, permission)
return unless path = regex.match(url) do |m|
"#{$~[:namespace]}/#{$~[:project]}"
end
embed.project_path = path
embed.permission = permission
end
# Returns a mapping representing whether the current user
# has permission to view the embed for the project.
# Determined in a batch
#
# @return [Hash<Embed, Boolean>]
def user_access_by_embed
strong_memoize(:user_access_by_embed) do
unique_embeds.each_with_object({}) do |embed, access|
project = projects_by_path[embed.project_path]
access[embed] = Ability.allowed?(user, embed.permission, project)
end
end
end
# Returns a unique list of embeds
#
# @return [Array<Embed>]
def unique_embeds
embeds_by_node.values.uniq
end
# Maps a project's full path to a Project object.
@ -74,22 +106,17 @@ module Banzai
def projects_by_path
strong_memoize(:projects_by_path) do
Project.eager_load(:route, namespace: [:route])
.where_full_path_in(paths_by_node.values.uniq)
.where_full_path_in(unique_project_paths)
.index_by(&:full_path)
end
end
# Returns a mapping representing whether the current user
# has permission to view the metrics for the project.
# Determined in a batch
# Returns a list of the full_paths of every project which
# has an embed in the doc
#
# @return [Hash<Project, Boolean>]
def user_access_by_path
strong_memoize(:user_access_by_path) do
projects_by_path.each_with_object({}) do |(path, project), access|
access[path] = Ability.allowed?(user, :read_environment, project)
end
end
# @return [Array<String>]
def unique_project_paths
embeds_by_node.values.map(&:project_path).uniq
end
end
end

View File

@ -30,6 +30,7 @@ module Banzai
Filter::ImageLazyLoadFilter,
Filter::ImageLinkFilter,
Filter::InlineMetricsFilter,
Filter::InlineGrafanaMetricsFilter,
Filter::TableOfContentsFilter,
Filter::AutolinkFilter,
Filter::ExternalLinkFilter,

View File

@ -12,6 +12,7 @@ module Gitlab
# @param project [Project]
# @param user [User]
# @param environment [Environment]
# @param options [Hash<Symbol,Any>]
# @param options - embedded [Boolean] Determines whether the
# dashboard is to be rendered as part of an
# issue or location other than the primary
@ -31,6 +32,8 @@ module Gitlab
# @param options - cluster [Cluster]
# @param options - cluster_type [Symbol] The level of
# cluster, one of [:admin, :project, :group]
# @param options - grafana_url [String] URL pointing
# to a grafana dashboard panel
# @return [Hash]
def find(project, user, options = {})
service_for(options)

View File

@ -18,6 +18,7 @@ module Gitlab
# @return [Gitlab::Metrics::Dashboard::Services::BaseService]
def call(params)
return SERVICES::CustomMetricEmbedService if custom_metric_embed?(params)
return SERVICES::GrafanaMetricEmbedService if grafana_metric_embed?(params)
return SERVICES::DynamicEmbedService if dynamic_embed?(params)
return SERVICES::DefaultEmbedService if params[:embedded]
return SERVICES::SystemDashboardService if system_dashboard?(params[:dashboard_path])
@ -40,6 +41,10 @@ module Gitlab
SERVICES::CustomMetricEmbedService.valid_params?(params)
end
def grafana_metric_embed?(params)
SERVICES::GrafanaMetricEmbedService.valid_params?(params)
end
def dynamic_embed?(params)
SERVICES::DynamicEmbedService.valid_params?(params)
end

View File

@ -14,17 +14,31 @@ module Gitlab
def regex
%r{
(?<url>
#{Regexp.escape(Gitlab.config.gitlab.url)}
\/#{Project.reference_pattern}
#{gitlab_pattern}
#{project_pattern}
(?:\/\-)?
\/environments
\/(?<environment>\d+)
\/metrics
(?<query>
\?[a-zA-Z0-9%.()+_=-]+
(&[a-zA-Z0-9%.()+_=-]+)*
)?
(?<anchor>\#[a-z0-9_-]+)?
#{query_pattern}
#{anchor_pattern}
)
}x
end
# Matches dashboard urls for a Grafana embed.
#
# EX - https://<host>/<namespace>/<project>/grafana/metrics_dashboard
def grafana_regex
%r{
(?<url>
#{gitlab_pattern}
#{project_pattern}
(?:\/\-)?
\/grafana
\/metrics_dashboard
#{query_pattern}
#{anchor_pattern}
)
}x
end
@ -45,6 +59,24 @@ module Gitlab
def build_dashboard_url(*args)
Gitlab::Routing.url_helpers.metrics_dashboard_namespace_project_environment_url(*args)
end
private
def gitlab_pattern
Regexp.escape(Gitlab.config.gitlab.url)
end
def project_pattern
"\/#{Project.reference_pattern}"
end
def query_pattern
'(?<query>\?[a-zA-Z0-9%.()+_=-]+(&[a-zA-Z0-9%.()+_=-]+)*)?'
end
def anchor_pattern
'(?<anchor>\#[a-z0-9_-]+)?'
end
end
end
end

View File

@ -14,6 +14,7 @@ module Gitlab
NOTIFICATION_CHANNEL = 'workhorse:notifications'
ALLOWED_GIT_HTTP_ACTIONS = %w[git_receive_pack git_upload_pack info_refs].freeze
DETECT_HEADER = 'Gitlab-Workhorse-Detect-Content-Type'
ARCHIVE_FORMATS = %w(zip tar.gz tar.bz2 tar).freeze
include JwtAuthenticatable

View File

@ -8498,6 +8498,9 @@ msgstr ""
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
msgid "GroupSettings|cannot change when group contains projects with NPM packages"
msgstr ""
msgid "GroupSettings|remove the share with group lock from %{ancestor_group_name}"
msgstr ""
@ -17645,6 +17648,9 @@ msgstr ""
msgid "TransferGroup|Database is not supported."
msgstr ""
msgid "TransferGroup|Group contains projects with NPM packages."
msgstr ""
msgid "TransferGroup|Group is already a root group."
msgstr ""
@ -17672,6 +17678,9 @@ msgstr ""
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr ""
msgid "TransferProject|Root namespace can't be updated if project has NPM packages"
msgstr ""
msgid "TransferProject|Transfer failed, please contact an admin."
msgstr ""
@ -19209,6 +19218,9 @@ msgstr ""
msgid "You can test your .gitlab-ci.yml in %{linkStart}CI Lint%{linkEnd}."
msgstr ""
msgid "You can try again using %{begin_link}basic search%{end_link}"
msgstr ""
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""

View File

@ -30,7 +30,7 @@ module QA
yield dir
ensure
FileUtils.remove_entry(dir)
FileUtils.remove_entry(dir, true)
end
private

View File

@ -27,10 +27,16 @@ module QA
--hostname #{host_name}
--name #{@name}
--volume #{@volume_host_path}:/home/maven
#{@image} sh -c "sleep 60"
#{@image} sh -c "sleep 300"
CMD
shell "docker cp #{@volume_host_path}/. #{@name}:/home/maven"
shell "docker exec -t #{@name} sh -c 'cd /home/maven && mvn deploy -s settings.xml'"
# Stop the container when `mvn deploy` is finished otherwise
# the sleeping container will hold onto the files in @volume_host_path,
# which causes problems when they're created in a tmp dir
# that we want to delete
shell "docker stop #{@name}"
end
end
end

View File

@ -31,11 +31,13 @@ describe MetricsDashboard do
end
context 'when params are provided' do
let(:params) { { environment: environment } }
before do
allow(controller).to receive(:project).and_return(project)
allow(controller)
.to receive(:metrics_dashboard_params)
.and_return(environment: environment)
.and_return(params)
end
it 'returns the specified dashboard' do
@ -43,6 +45,15 @@ describe MetricsDashboard do
expect(json_response).not_to have_key('all_dashboards')
end
context 'when the params are in an alternate format' do
let(:params) { ActionController::Parameters.new({ environment: environment }).permit! }
it 'returns the specified dashboard' do
expect(json_response['dashboard']['dashboard']).to eq('Environment metrics')
expect(json_response).not_to have_key('all_dashboards')
end
end
context 'when parameters are provided and the list of all dashboards is required' do
before do
allow(controller).to receive(:include_all_dashboards?).and_return(true)

View File

@ -94,4 +94,87 @@ describe Projects::GrafanaApiController do
end
end
end
describe 'GET #metrics_dashboard' do
let(:service_result) { { status: :success, dashboard: '{}' } }
let(:params) do
{
format: :json,
embedded: true,
grafana_url: 'https://grafana.example.com',
namespace_id: project.namespace.full_path,
project_id: project.name
}
end
before do
allow(Gitlab::Metrics::Dashboard::Finder)
.to receive(:find)
.and_return(service_result)
end
context 'when the result is still processing' do
let(:service_result) { nil }
it 'returns 204 no content' do
get :metrics_dashboard, params: params
expect(response).to have_gitlab_http_status(:no_content)
end
end
context 'when the result was successful' do
it 'returns the dashboard response' do
get :metrics_dashboard, params: params
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to eq({
'dashboard' => '{}',
'status' => 'success'
})
end
end
context 'when an error has occurred' do
shared_examples_for 'error response' do |http_status|
it "returns #{http_status}" do
get :metrics_dashboard, params: params
expect(response).to have_gitlab_http_status(http_status)
expect(json_response['status']).to eq('error')
expect(json_response['message']).to eq('error message')
end
end
context 'with an error accessing grafana' do
let(:service_result) do
{
http_status: :service_unavailable,
status: :error,
message: 'error message'
}
end
it_behaves_like 'error response', :service_unavailable
end
context 'with a processing error' do
let(:service_result) { { status: :error, message: 'error message' } }
it_behaves_like 'error response', :bad_request
end
end
context 'when grafana embeds are not enabled' do
before do
stub_feature_flags(gfm_grafana_integration: false)
end
it 'returns 403 immediately' do
get :metrics_dashboard, params: params
expect(response).to have_gitlab_http_status(:forbidden)
end
end
end
end

View File

@ -28,6 +28,7 @@ describe 'User uses header search field', :js do
context 'when using the keyboard shortcut' do
before do
find('#search.js-autocomplete-disabled')
find('body').native.send_keys('s')
end

View File

@ -0,0 +1,81 @@
# frozen_string_literal: true
require 'spec_helper'
describe Banzai::Filter::InlineGrafanaMetricsFilter do
include FilterSpecHelper
let_it_be(:project) { create(:project) }
let_it_be(:grafana_integration) { create(:grafana_integration, project: project) }
let(:input) { %(<a href="#{url}">example</a>) }
let(:doc) { filter(input) }
let(:url) { grafana_integration.grafana_url + dashboard_path }
let(:dashboard_path) do
'/d/XDaNK6amz/gitlab-omnibus-redis' \
'?from=1570397739557&to=1570484139557' \
'&var-instance=All&panelId=14'
end
context 'when feature flag is disabled' do
before do
stub_feature_flags(gfm_grafana_integration: false)
end
it 'leaves the markdown unchanged' do
expect(unescape(doc.to_s)).to eq(input)
end
end
it 'appends a metrics charts placeholder with dashboard url after metrics links' do
node = doc.at_css('.js-render-metrics')
expect(node).to be_present
dashboard_url = urls.project_grafana_api_metrics_dashboard_url(
project,
embedded: true,
grafana_url: url,
start: "2019-10-06T21:35:39Z",
end: "2019-10-07T21:35:39Z"
)
expect(node.attribute('data-dashboard-url').to_s).to eq(dashboard_url)
end
context 'when the dashboard link is part of a paragraph' do
let(:paragraph) { %(This is an <a href="#{url}">example</a> of metrics.) }
let(:input) { %(<p>#{paragraph}</p>) }
it 'appends the charts placeholder after the enclosing paragraph' do
expect(unescape(doc.at_css('p').to_s)).to include(paragraph)
expect(doc.at_css('.js-render-metrics')).to be_present
end
end
context 'when grafana is not configured' do
before do
allow(project).to receive(:grafana_integration).and_return(nil)
end
it 'leaves the markdown unchanged' do
expect(unescape(doc.to_s)).to eq(input)
end
end
context 'when parameters are missing' do
let(:dashboard_path) { '/d/XDaNK6amz/gitlab-omnibus-redis' }
it 'leaves the markdown unchanged' do
expect(unescape(doc.to_s)).to eq(input)
end
end
private
# Nokogiri escapes the URLs, but we don't care about that
# distinction for the purposes of this filter
def unescape(html)
CGI.unescapeHTML(html)
end
end

View File

@ -18,30 +18,48 @@ describe Banzai::Filter::InlineMetricsRedactorFilter do
end
context 'with a metrics charts placeholder' do
shared_examples_for 'a supported metrics dashboard url' do
context 'no user is logged in' do
it 'redacts the placeholder' do
expect(doc.to_s).to be_empty
end
end
context 'the user does not have permission do see charts' do
let(:doc) { filter(input, current_user: build(:user)) }
it 'redacts the placeholder' do
expect(doc.to_s).to be_empty
end
end
context 'the user has requisite permissions' do
let(:user) { create(:user) }
let(:doc) { filter(input, current_user: user) }
it 'leaves the placeholder' do
project.add_maintainer(user)
expect(doc.to_s).to eq input
end
end
end
let(:input) { %(<div class="js-render-metrics" data-dashboard-url="#{url}"></div>) }
context 'no user is logged in' do
it 'redacts the placeholder' do
expect(doc.to_s).to be_empty
end
it_behaves_like 'a supported metrics dashboard url'
context 'for a grafana dashboard' do
let(:url) { urls.project_grafana_api_metrics_dashboard_url(project, embedded: true) }
it_behaves_like 'a supported metrics dashboard url'
end
context 'the user does not have permission do see charts' do
let(:doc) { filter(input, current_user: build(:user)) }
it 'redacts the placeholder' do
expect(doc.to_s).to be_empty
end
end
context 'the user has requisite permissions' do
let(:user) { create(:user) }
let(:doc) { filter(input, current_user: user) }
context 'for an internal non-dashboard url' do
let(:url) { urls.project_url(project) }
it 'leaves the placeholder' do
project.add_maintainer(user)
expect(doc.to_s).to eq input
expect(doc.to_s).to be_empty
end
end
end

View File

@ -75,6 +75,17 @@ describe Gitlab::Metrics::Dashboard::ServiceSelector do
it { is_expected.to be Metrics::Dashboard::CustomMetricEmbedService }
end
context 'with a grafana link' do
let(:arguments) do
{
embedded: true,
grafana_url: 'https://grafana.example.com'
}
end
it { is_expected.to be Metrics::Dashboard::GrafanaMetricEmbedService }
end
end
end
end

View File

@ -3,13 +3,41 @@
require 'spec_helper'
describe Gitlab::Metrics::Dashboard::Url do
describe '#regex' do
it 'returns a regular expression' do
expect(described_class.regex).to be_a Regexp
end
shared_examples_for 'a regex which matches the expected url' do
it { is_expected.to be_a Regexp }
it 'matches a metrics dashboard link with named params' do
url = Gitlab::Routing.url_helpers.metrics_namespace_project_environment_url(
expect(subject).to match url
subject.match(url) do |m|
expect(m.named_captures).to eq expected_params
end
end
end
shared_examples_for 'does not match non-matching urls' do
it 'does not match other gitlab urls that contain the term metrics' do
url = Gitlab::Routing.url_helpers.active_common_namespace_project_prometheus_metrics_url('foo', 'bar', :json)
expect(subject).not_to match url
end
it 'does not match other gitlab urls' do
url = Gitlab.config.gitlab.url
expect(subject).not_to match url
end
it 'does not match non-gitlab urls' do
url = 'https://www.super_awesome_site.com/'
expect(subject).not_to match url
end
end
describe '#regex' do
let(:url) do
Gitlab::Routing.url_helpers.metrics_namespace_project_environment_url(
'foo',
'bar',
1,
@ -18,8 +46,10 @@ describe Gitlab::Metrics::Dashboard::Url do
group: 'awesome group',
anchor: 'title'
)
end
expected_params = {
let(:expected_params) do
{
'url' => url,
'namespace' => 'foo',
'project' => 'bar',
@ -27,31 +57,40 @@ describe Gitlab::Metrics::Dashboard::Url do
'query' => '?dashboard=config%2Fprometheus%2Fcommon_metrics.yml&group=awesome+group&start=2019-08-02T05%3A43%3A09.000Z',
'anchor' => '#title'
}
expect(described_class.regex).to match url
described_class.regex.match(url) do |m|
expect(m.named_captures).to eq expected_params
end
end
it 'does not match other gitlab urls that contain the term metrics' do
url = Gitlab::Routing.url_helpers.active_common_namespace_project_prometheus_metrics_url('foo', 'bar', :json)
subject { described_class.regex }
expect(described_class.regex).not_to match url
it_behaves_like 'a regex which matches the expected url'
it_behaves_like 'does not match non-matching urls'
end
describe '#grafana_regex' do
let(:url) do
Gitlab::Routing.url_helpers.namespace_project_grafana_api_metrics_dashboard_url(
'foo',
'bar',
start: '2019-08-02T05:43:09.000Z',
dashboard: 'config/prometheus/common_metrics.yml',
group: 'awesome group',
anchor: 'title'
)
end
it 'does not match other gitlab urls' do
url = Gitlab.config.gitlab.url
expect(described_class.regex).not_to match url
let(:expected_params) do
{
'url' => url,
'namespace' => 'foo',
'project' => 'bar',
'query' => '?dashboard=config%2Fprometheus%2Fcommon_metrics.yml&group=awesome+group&start=2019-08-02T05%3A43%3A09.000Z',
'anchor' => '#title'
}
end
it 'does not match non-gitlab urls' do
url = 'https://www.super_awesome_site.com/'
subject { described_class.grafana_regex }
expect(described_class.regex).not_to match url
end
it_behaves_like 'a regex which matches the expected url'
it_behaves_like 'does not match non-matching urls'
end
describe '#build_dashboard_url' do

View File

@ -57,14 +57,14 @@ RSpec.describe Release do
subject { release.assets_count }
it 'returns the number of sources' do
is_expected.to eq(Releases::Source::FORMATS.count)
is_expected.to eq(Gitlab::Workhorse::ARCHIVE_FORMATS.count)
end
context 'when a links exists' do
let!(:link) { create(:release_link, release: release) }
it 'counts the link as an asset' do
is_expected.to eq(1 + Releases::Source::FORMATS.count)
is_expected.to eq(1 + Gitlab::Workhorse::ARCHIVE_FORMATS.count)
end
it "excludes sources count when asked" do

View File

@ -11,7 +11,7 @@ describe Releases::Source do
it 'returns all formats of sources' do
expect(subject.map(&:format))
.to match_array(described_class::FORMATS)
.to match_array(Gitlab::Workhorse::ARCHIVE_FORMATS)
end
end

View File

@ -1,7 +1,6 @@
# frozen_string_literal: true
shared_examples 'archive download buttons' do
let(:formats) { %w(zip tar.gz tar.bz2 tar) }
let(:path_to_visit) { project_path(project) }
let(:ref) { project.default_branch }
@ -13,7 +12,7 @@ shared_examples 'archive download buttons' do
context 'private project' do
it 'shows archive download buttons with external storage URL prepended and user token appended to their href' do
formats.each do |format|
Gitlab::Workhorse::ARCHIVE_FORMATS.each do |format|
path = archive_path(project, ref, format)
uri = URI('https://cdn.gitlab.com')
uri.path = path
@ -28,7 +27,7 @@ shared_examples 'archive download buttons' do
let(:project) { create(:project, :repository, :public) }
it 'shows archive download buttons with external storage URL prepended to their href' do
formats.each do |format|
Gitlab::Workhorse::ARCHIVE_FORMATS.each do |format|
path = archive_path(project, ref, format)
uri = URI('https://cdn.gitlab.com')
uri.path = path
@ -45,7 +44,7 @@ shared_examples 'archive download buttons' do
end
it 'shows default archive download buttons' do
formats.each do |format|
Gitlab::Workhorse::ARCHIVE_FORMATS.each do |format|
path = archive_path(project, ref, format)
expect(page).to have_link format, href: path