Commit e37e4ea2 authored by GitLab Bot's avatar GitLab Bot

Merge remote-tracking branch 'upstream/master' into ce-to-ee-2018-03-02

# Conflicts:
#	config/webpack.config.js
#	db/schema.rb
#	locale/gitlab.pot

[ci skip]
parents 68a13836 40c61acb
......@@ -426,7 +426,7 @@ group :ed25519 do
end
# Gitaly GRPC client
gem 'gitaly-proto', '~> 0.85.0', require: 'gitaly'
gem 'gitaly-proto', '~> 0.87.0', require: 'gitaly'
# Locked until https://github.com/google/protobuf/issues/4210 is closed
gem 'google-protobuf', '= 3.5.1'
......
......@@ -309,7 +309,7 @@ GEM
po_to_json (>= 1.0.0)
rails (>= 3.2.0)
gherkin-ruby (0.3.2)
gitaly-proto (0.85.0)
gitaly-proto (0.87.0)
google-protobuf (~> 3.1)
grpc (~> 1.0)
github-linguist (5.3.3)
......@@ -1091,7 +1091,7 @@ DEPENDENCIES
gettext (~> 3.2.2)
gettext_i18n_rails (~> 1.8.0)
gettext_i18n_rails_js (~> 1.2.0)
gitaly-proto (~> 0.85.0)
gitaly-proto (~> 0.87.0)
github-linguist (~> 5.3.3)
gitlab-flowdock-git-hook (~> 1.0.1)
gitlab-license (~> 1.0)
......
......@@ -99,12 +99,6 @@
</p>
`;
},
gitlabRunnerDescription() {
return _.escape(s__(
`ClusterIntegration|GitLab Runner is the open source project that is used to run your jobs
and send the results back to GitLab.`,
));
},
prometheusDescription() {
return sprintf(
_.escape(s__(
......@@ -256,6 +250,22 @@
>
</div>
</application-row>
<application-row
id="runner"
:title="applications.runner.title"
title-link="https://docs.gitlab.com/runner/"
:status="applications.runner.status"
:status-reason="applications.runner.statusReason"
:request-status="applications.runner.requestStatus"
:request-reason="applications.runner.requestReason"
>
<div slot="description">
{{ s__(`ClusterIntegration|GitLab Runner connects to this
project's repository and executes CI/CD jobs,
pushing results back and deploying,
applications to production.`) }}
</div>
</application-row>
<!--
NOTE: Don't forget to update `clusters.scss`
min-height for this block and uncomment `application_spec` tests
......
......@@ -14,8 +14,6 @@ class Projects::CommitsController < Projects::ApplicationController
@merge_request = MergeRequestsFinder.new(current_user, project_id: @project.id).execute.opened
.find_by(source_project: @project, source_branch: @ref, target_branch: @repository.root_ref)
# https://gitlab.com/gitlab-org/gitaly/issues/931
Gitlab::GitalyClient.allow_n_plus_1_calls do
respond_to do |format|
format.html
format.atom { render layout: 'xml.atom' }
......@@ -29,11 +27,8 @@ class Projects::CommitsController < Projects::ApplicationController
end
end
end
end
def signatures
# https://gitlab.com/gitlab-org/gitaly/issues/931
Gitlab::GitalyClient.allow_n_plus_1_calls do
respond_to do |format|
format.json do
render json: {
......@@ -47,7 +42,6 @@ class Projects::CommitsController < Projects::ApplicationController
end
end
end
end
private
......
......@@ -15,7 +15,7 @@ module Clusters
end
def install_command
Gitlab::Kubernetes::Helm::InstallCommand.new(name, install_helm: true)
Gitlab::Kubernetes::Helm::InitCommand.new(name)
end
end
end
......
......@@ -5,6 +5,7 @@ module Clusters
include ::Clusters::Concerns::ApplicationCore
include ::Clusters::Concerns::ApplicationStatus
include ::Clusters::Concerns::ApplicationData
include AfterCommitQueue
default_value_for :ingress_type, :nginx
......@@ -29,12 +30,12 @@ module Clusters
'stable/nginx-ingress'
end
def chart_values_file
"#{Rails.root}/vendor/#{name}/values.yaml"
end
def install_command
Gitlab::Kubernetes::Helm::InstallCommand.new(name, chart: chart, chart_values_file: chart_values_file)
Gitlab::Kubernetes::Helm::InstallCommand.new(
name,
chart: chart,
values: values
)
end
def schedule_status_update
......
......@@ -7,6 +7,7 @@ module Clusters
include ::Clusters::Concerns::ApplicationCore
include ::Clusters::Concerns::ApplicationStatus
include ::Clusters::Concerns::ApplicationData
default_value_for :version, VERSION
......@@ -30,12 +31,12 @@ module Clusters
80
end
def chart_values_file
"#{Rails.root}/vendor/#{name}/values.yaml"
end
def install_command
Gitlab::Kubernetes::Helm::InstallCommand.new(name, chart: chart, chart_values_file: chart_values_file)
Gitlab::Kubernetes::Helm::InstallCommand.new(
name,
chart: chart,
values: values
)
end
def proxy_client
......
module Clusters
module Applications
class Runner < ActiveRecord::Base
VERSION = '0.1.13'.freeze
self.table_name = 'clusters_applications_runners'
include ::Clusters::Concerns::ApplicationCore
include ::Clusters::Concerns::ApplicationStatus
include ::Clusters::Concerns::ApplicationData
belongs_to :runner, class_name: 'Ci::Runner', foreign_key: :runner_id
delegate :project, to: :cluster
default_value_for :version, VERSION
def chart
"#{name}/gitlab-runner"
end
def repository
'https://charts.gitlab.io'
end
def values
content_values.to_yaml
end
def install_command
Gitlab::Kubernetes::Helm::InstallCommand.new(
name,
chart: chart,
values: values,
repository: repository
)
end
private
def ensure_runner
runner || create_and_assign_runner
end
def create_and_assign_runner
transaction do
project.runners.create!(name: 'kubernetes-cluster', tag_list: %w(kubernetes cluster)).tap do |runner|
update!(runner_id: runner.id)
end
end
end
def gitlab_url
Gitlab::Routing.url_helpers.root_url(only_path: false)
end
def specification
{
"gitlabUrl" => gitlab_url,
"runnerToken" => ensure_runner.token
}
end
def content_values
specification.merge(YAML.load_file(chart_values_file))
end
end
end
end
......@@ -8,7 +8,8 @@ module Clusters
APPLICATIONS = {
Applications::Helm.application_name => Applications::Helm,
Applications::Ingress.application_name => Applications::Ingress,
Applications::Prometheus.application_name => Applications::Prometheus
Applications::Prometheus.application_name => Applications::Prometheus,
Applications::Runner.application_name => Applications::Runner
}.freeze
belongs_to :user
......@@ -24,6 +25,7 @@ module Clusters
has_one :application_helm, class_name: 'Clusters::Applications::Helm'
has_one :application_ingress, class_name: 'Clusters::Applications::Ingress'
has_one :application_prometheus, class_name: 'Clusters::Applications::Prometheus'
has_one :application_runner, class_name: 'Clusters::Applications::Runner'
accepts_nested_attributes_for :provider_gcp, update_only: true
accepts_nested_attributes_for :platform_kubernetes, update_only: true
......@@ -70,7 +72,8 @@ module Clusters
[
application_helm || build_application_helm,
application_ingress || build_application_ingress,
application_prometheus || build_application_prometheus
application_prometheus || build_application_prometheus,
application_runner || build_application_runner
]
end
......
module Clusters
module Concerns
module ApplicationData
extend ActiveSupport::Concern
included do
def repository
nil
end
def values
File.read(chart_values_file)
end
private
def chart_values_file
"#{Rails.root}/vendor/#{name}/values.yaml"
end
end
end
end
end
......@@ -19,6 +19,7 @@ class Commit
attr_accessor :project, :author
attr_accessor :redacted_description_html
attr_accessor :redacted_title_html
attr_reader :gpg_commit
DIFF_SAFE_LINES = Gitlab::Git::DiffCollection::DEFAULT_LIMITS[:max_lines]
......@@ -110,6 +111,7 @@ class Commit
@raw = raw_commit
@project = project
@statuses = {}
@gpg_commit = Gitlab::Gpg::Commit.new(self) if project
end
def id
......@@ -452,8 +454,4 @@ class Commit
def merged_merge_request_no_cache(user)
MergeRequestsFinder.new(user, project_id: project.id).find_by(merge_commit_sha: id) if merge_commit?
end
def gpg_commit
@gpg_commit ||= Gitlab::Gpg::Commit.new(self)
end
end
......@@ -141,7 +141,7 @@ class CommitStatus < ActiveRecord::Base
end
def group_name
name.to_s.gsub(%r{\d+[\s:/\\]+\d+\s*}, '').strip
name.to_s.gsub(%r{\d+[\.\s:/\\]+\d+\s*}, '').strip
end
def failed_but_allowed?
......
......@@ -10,6 +10,7 @@
install_helm_path: install_applications_namespace_project_cluster_path(@cluster.project.namespace, @cluster.project, @cluster, :helm),
install_ingress_path: install_applications_namespace_project_cluster_path(@cluster.project.namespace, @cluster.project, @cluster, :ingress),
install_prometheus_path: install_applications_namespace_project_cluster_path(@cluster.project.namespace, @cluster.project, @cluster, :prometheus),
install_runner_path: install_applications_namespace_project_cluster_path(@cluster.project.namespace, @cluster.project, @cluster, :runner),
toggle_status: @cluster.enabled? ? 'true': 'false',
cluster_status: @cluster.status_name,
cluster_status_reason: @cluster.status_reason,
......
---
title: Allow installation of GitLab Runner with a single click
merge_request: 17134
author:
type: added
---
title: Allow CI/CD Jobs being grouped on version strings
merge_request:
author:
type: added
......@@ -50,6 +50,10 @@ function generateEntries() {
const manualEntries = {
monitoring: './monitoring/monitoring_bundle.js',
mr_notes: './mr_notes/index.js',
<<<<<<< HEAD
=======
protected_branches: './protected_branches',
>>>>>>> upstream/master
terminal: './terminal/terminal_bundle.js',
two_factor_auth: './two_factor_auth.js',
......
class CreateClustersApplicationsRunners < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
create_table :clusters_applications_runners do |t|
t.references :cluster, null: false, foreign_key: { on_delete: :cascade }
t.references :runner, references: :ci_runners
t.index :runner_id
t.index :cluster_id, unique: true
t.integer :status, null: false
t.timestamps_with_timezone null: false
t.string :version, null: false
t.text :status_reason
end
add_concurrent_foreign_key :clusters_applications_runners, :ci_runners,
column: :runner_id,
on_delete: :nullify
end
def down
if foreign_keys_for(:clusters_applications_runners, :runner_id).any?
remove_foreign_key :clusters_applications_runners, column: :runner_id
end
drop_table :clusters_applications_runners
end
end
......@@ -677,6 +677,19 @@ ActiveRecord::Schema.define(version: 20180301084653) do
t.datetime_with_timezone "updated_at", null: false
end
create_table "clusters_applications_runners", force: :cascade do |t|
t.integer "cluster_id", null: false
t.integer "runner_id"
t.integer "status", null: false
t.datetime_with_timezone "created_at", null: false
t.datetime_with_timezone "updated_at", null: false
t.string "version", null: false
t.text "status_reason"
end
add_index "clusters_applications_runners", ["cluster_id"], name: "index_clusters_applications_runners_on_cluster_id", unique: true, using: :btree
add_index "clusters_applications_runners", ["runner_id"], name: "index_clusters_applications_runners_on_runner_id", using: :btree
create_table "container_repositories", force: :cascade do |t|
t.integer "project_id", null: false
t.string "name", null: false
......@@ -2530,7 +2543,12 @@ ActiveRecord::Schema.define(version: 20180301084653) do
add_foreign_key "cluster_providers_gcp", "clusters", on_delete: :cascade
add_foreign_key "clusters", "users", on_delete: :nullify
add_foreign_key "clusters_applications_helm", "clusters", on_delete: :cascade
<<<<<<< HEAD
add_foreign_key "clusters_applications_ingress", "clusters", on_delete: :cascade
=======
add_foreign_key "clusters_applications_runners", "ci_runners", column: "runner_id", name: "fk_02de2ded36", on_delete: :nullify
add_foreign_key "clusters_applications_runners", "clusters", on_delete: :cascade
>>>>>>> upstream/master
add_foreign_key "container_repositories", "projects"
add_foreign_key "deploy_keys_projects", "projects", name: "fk_58a901ca7e", on_delete: :cascade
add_foreign_key "deployments", "projects", name: "fk_b9a3851b82", on_delete: :cascade
......
......@@ -23,7 +23,7 @@ requests from the API are logged to a separate file in `api_json.log`.
Each line contains a JSON line that can be ingested by Elasticsearch, Splunk, etc. For example:
```json
{"method":"GET","path":"/gitlab/gitlab-ce/issues/1234","format":"html","controller":"Projects::IssuesController","action":"show","status":200,"duration":229.03,"view":174.07,"db":13.24,"time":"2017-08-08T20:15:54.821Z","params":{"namespace_id":"gitlab","project_id":"gitlab-ce","id":"1234"},"remote_ip":"18.245.0.1","user_id":1,"username":"admin"}
{"method":"GET","path":"/gitlab/gitlab-ce/issues/1234","format":"html","controller":"Projects::IssuesController","action":"show","status":200,"duration":229.03,"view":174.07,"db":13.24,"time":"2017-08-08T20:15:54.821Z","params":[{"key":"param_key","value":"param_value"}],"remote_ip":"18.245.0.1","user_id":1,"username":"admin","gitaly_calls":76}
```
In this example, you can see this was a GET request for a specific issue. Notice each line also contains performance data:
......@@ -31,6 +31,7 @@ In this example, you can see this was a GET request for a specific issue. Notice
1. `duration`: the total time taken to retrieve the request
2. `view`: total time taken inside the Rails views
3. `db`: total time to retrieve data from the database
4. `gitaly_calls`: total number of calls made to Gitaly
User clone/fetch activity using http transport appears in this log as `action: git_upload_pack`.
......
......@@ -121,8 +121,9 @@ The basic requirements is that there are two numbers separated with one of
the following (you can even use them interchangeably):
- a space
- a backslash (`/`)
- a forward slash (`/`)
- a colon (`:`)
- a dot (`.`)
>**Note:**
More specifically, [it uses][regexp] this regular expression: `\d+[\s:\/\\]+\d+\s*`.
......
......@@ -120,6 +120,7 @@ added directly to your configured cluster. Those applications are needed for
| [Helm Tiller](https://docs.helm.sh/) | 10.2+ | Helm is a package manager for Kubernetes and is required to install all the other applications. It will be automatically installed as a dependency when you try to install a different app. It is installed in its own pod inside the cluster which can run the `helm` CLI in a safe environment. |
| [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) | 10.2+ | Ingress can provide load 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. |
| [Prometheus](https://prometheus.io/docs/introduction/overview/) | 10.4+ | Prometheus is an open-source monitoring and alerting system useful to supervise your deployed applications |
| [GitLab Runner](https://docs.gitlab.com/runner/) | 10.6+ | GitLab Runner is the open source project that is used to run your jobs and send the results back to GitLab. It is used in conjunction with [GitLab CI](https://about.gitlab.com/features/gitlab-ci-cd/), the open-source continuous integration service included with GitLab that coordinates the jobs. |
## Getting the external IP address
......
......@@ -250,6 +250,45 @@ module Gitlab
end
end
def extract_signature_lazily(repository, commit_id)
BatchLoader.for({ repository: repository, commit_id: commit_id }).batch do |items, loader|
items_by_repo = items.group_by { |i| i[:repository] }
items_by_repo.each do |repo, items|
commit_ids = items.map { |i| i[:commit_id] }
signatures = batch_signature_extraction(repository, commit_ids)
signatures.each do |commit_sha, signature_data|
loader.call({ repository: repository, commit_id: commit_sha }, signature_data)
end
end
end
end
def batch_signature_extraction(repository, commit_ids)
repository.gitaly_migrate(:extract_commit_signature_in_batch) do |is_enabled|
if is_enabled
gitaly_batch_signature_extraction(repository, commit_ids)
else
rugged_batch_signature_extraction(repository, commit_ids)
end
end
end
def gitaly_batch_signature_extraction(repository, commit_ids)
repository.gitaly_commit_client.get_commit_signatures(commit_ids)
end
def rugged_batch_signature_extraction(repository, commit_ids)
commit_ids.each_with_object({}) do |commit_id, signatures|
signature_data = rugged_extract_signature(repository, commit_id)
next unless signature_data
signatures[commit_id] = signature_data
end
end
def rugged_extract_signature(repository, commit_id)
begin
Rugged::Commit.extract_signature(repository.rugged, commit_id)
......
......@@ -319,6 +319,23 @@ module Gitlab
[signature, signed_text]
end
def get_commit_signatures(commit_ids)
request = Gitaly::GetCommitSignaturesRequest.new(repository: @gitaly_repo, commit_ids: commit_ids)
response = GitalyClient.call(@repository.storage, :commit_service, :get_commit_signatures, request)
signatures = Hash.new { |h, k| h[k] = [''.b, ''.b] }
current_commit_id = nil
response.each do |message|
current_commit_id = message.commit_id if message.commit_id.present?
signatures[current_commit_id].first << message.signature
signatures[current_commit_id].last << message.signed_text
end
signatures
end
private
def call_commit_diff(request_params, options = {})
......
module Gitlab
module Gpg
class Commit
include Gitlab::Utils::StrongMemoize
def initialize(commit)
@commit = commit
repo = commit.project.repository.raw_repository
@signature_text, @signed_text = Gitlab::Git::Commit.extract_signature(repo, commit.sha)
@signature_data = Gitlab::Git::Commit.extract_signature_lazily(repo, commit.sha || commit.id)
end
def signature_text
strong_memoize(:signature_text) do
@signature_data&.itself && @signature_data[0]
end
end
def signed_text
strong_memoize(:signed_text) do
@signature_data&.itself && @signature_data[1]
end
end
def has_signature?
!!(@signature_text && @signed_text)
!!(signature_text && signed_text)
end
def signature
......@@ -53,7 +67,7 @@ module Gitlab
end
def verified_signature
@verified_signature ||= GPGME::Crypto.new.verify(@signature_text, signed_text: @signed_text) do |verified_signature|
@verified_signature ||= GPGME::Crypto.new.verify(signature_text, signed_text: signed_text) do |verified_signature|
break verified_signature
end
end
......
module Gitlab
module Kubernetes
class ConfigMap
def initialize(name, values)
@name = name
@values = values
end
def generate
resource = ::Kubeclient::Resource.new
resource.metadata = metadata
resource.data = { values: values }
resource
end
private
attr_reader :name, :values
def metadata
{
name: config_map_name,
namespace: namespace,
labels: { name: config_map_name }
}
end
def config_map_name
"values-content-configuration-#{name}"
end
def namespace
Gitlab::Kubernetes::Helm::NAMESPACE
end
end
end
end
......@@ -9,7 +9,8 @@ module Gitlab
def install(command)
@namespace.ensure_exists!
@kubeclient.create_pod(pod_resource(command))
create_config_map(command) if command.config_map?
@kubeclient.create_pod(command.pod_resource)
end
##
......@@ -33,8 +34,10 @@ module Gitlab
private
def pod_resource(command)
Gitlab::Kubernetes::Helm::Pod.new(command, @namespace.name, @kubeclient).generate
def create_config_map(command)
command.config_map_resource.tap do |config_map_resource|
@kubeclient.create_config_map(config_map_resource)
end
end
end
end
......
module Gitlab
module Kubernetes
module Helm
class BaseCommand
attr_reader :name
def initialize(name)
@name = name
end
def pod_resource
Gitlab::Kubernetes::Helm::Pod.new(self, namespace).generate
end
def generate_script
<<~HEREDOC
set -eo pipefail
apk add -U ca-certificates openssl >/dev/null
wget -q -O - https://kubernetes-helm.storage.googleapis.com/helm-v#{Gitlab::Kubernetes::Helm::HELM_VERSION}-linux-amd64.tar.gz | tar zxC /tmp >/dev/null
mv /tmp/linux-amd64/helm /usr/bin/
HEREDOC
end
def config_map?
false
end
def pod_name
"install-#{name}"
end
private
def namespace
Gitlab::Kubernetes::Helm::NAMESPACE
end
end
end
end
end
module Gitlab
module Kubernetes
module Helm
class InitCommand < BaseCommand
def generate_script
super + [
init_helm_command
].join("\n")
end
private
def init_helm_command
"helm init >/dev/null"
end
end
end
end
end
module Gitlab
module Kubernetes
module Helm
class InstallCommand
attr_reader :name, :install_helm, :chart, :chart_values_file
class InstallCommand < BaseCommand
attr_reader :name, :chart, :repository, :values
def initialize(name, install_helm: false, chart: false, chart_values_file: false)
def initialize(name, chart:, values:, repository: nil)
@name = name
@install_helm = install_helm
@chart = chart
@chart_values_file = chart_values_file
@values = values
@repository = repository
end
def pod_name
"install-#{name}"
def generate_script
super + [
init_command,
repository_command,
script_command
].compact.join("\n")
end
def generate_script(namespace_name)
[
install_dps_command,
init_command,
complete_command(namespace_name)
].join("\n")
def config_map?
true
end
def config_map_resource
Gitlab::Kubernetes::ConfigMap.new(name, values).generate
end
private
def init_command
if install_helm
'helm init >/dev/null'
else
'helm init --client-only >/dev/null'
end
end
def complete_command(namespace_name)
return unless chart
if chart_values_file
"helm install #{chart} --name #{name} --namespace #{namespace_name} -f /data/helm/#{name}/config/values.yaml >/dev/null"
else
"helm install #{chart} --name #{name} --namespace #{namespace_name} >/dev/null"
end
def repository_command
"helm repo add #{name} #{repository}" if repository
end
def install_dps_command
def script_command
<<~HEREDOC
set -eo pipefail
apk add -U ca-certificates openssl >/dev/null
wget -q -O - https://kubernetes-helm.storage.googleapis.com/helm-v#{Gitlab::Kubernetes::Helm::HELM_VERSION}-linux-amd64.tar.gz | tar zxC /tmp >/dev/null
mv /tmp/linux-amd64/helm /usr/bin/
helm install #{chart} --name #{name} --namespace #{Gitlab::Kubernetes::Helm::NAMESPACE} -f /data/helm/#{name}/config/values.yaml >/dev/null
HEREDOC
end
end
......
......@@ -2,18 +2,17 @@ module Gitlab
module Kubernetes
module Helm
class Pod
def initialize(command, namespace_name, kubeclient)
def initialize(command, namespace_name)
@command = command
@namespace_name = namespace_name
@kubeclient = kubeclient
end
def generate
spec = { containers: [container_specification], restartPolicy: 'Never' }
if command.chart_values_file
create_config_map
if command.config_map?
spec[:volumes] = volumes_specification
spec[:containers][0][:volumeMounts] = volume_mounts_specification
end
::Kubeclient::Resource.new(metadata: metadata, spec: spec)
......@@ -21,18 +20,16 @@ module Gitlab
private
attr_reader :command, :namespace_name, :kubeclient
attr_reader :command, :namespace_name, :kubeclient, :config_map
def container_specification
container = {
{
name: 'helm',
image: 'alpine:3.6',
env: generate_pod_env(command),
command: %w(/bin/sh),
args: %w(-c $(COMMAND_SCRIPT))
}
container[:volumeMounts] = volume_mounts_specification if command.chart_values_file
container
end
def labels
......@@ -50,13 +47,12 @@ module Gitlab
}
end
def volume_mounts_specification
[
def generate_pod_env(command)
{
name: 'configuration-volume',
mountPath: "/data/helm/#{command.name}/config"
}
]
HELM_VERSION: Gitlab::Kubernetes::Helm::HELM_VERSION,
TILLER_NAMESPACE: namespace_name,
COMMAND_SCRIPT: command.generate_script
}.map { |key, value| { name: key, value: value } }
end
def volumes_specification
......@@ -71,23 +67,13 @@ module Gitlab
]
end
def generate_pod_env(command)
def volume_mounts_specification
[
{
HELM_VERSION: Gitlab::Kubernetes::Helm::HELM_VERSION,
TILLER_NAMESPACE: namespace_name,
COMMAND_SCRIPT: command.generate_script(namespace_name)
}.map { |key, value| { name: key, value: value } }
end
def create_config_map
resource = ::Kubeclient::Resource.new
resource.metadata = {
name: "values-content-configuration-#{command.name}",
namespace: namespace_name,
labels: { name: "values-content-configuration-#{command.name}" }
name: 'configuration-volume',
mountPath: "/data/helm/#{command.name}/config"
}
resource.data = { values: File.read(command.chart_values_file) }
kubeclient.create_config_map(resource)
]
end
end
end
......
......@@ -8,8 +8,13 @@ msgid ""
msgstr ""
"Project-Id-Version: gitlab 1.0.0\n"
"Report-Msgid-Bugs-To: \n"
<<<<<<< HEAD
"POT-Creation-Date: 2018-03-01 22:35+0100\n"
"PO-Revision-Date: 2018-03-01 22:35+0100\n"
=======
"POT-Creation-Date: 2018-03-01 18:03+0100\n"
"PO-Revision-Date: 2018-03-01 18:03+0100\n"
>>>>>>> upstream/master
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
......@@ -138,9 +143,12 @@ msgstr ""
msgid "Add Contribution guide"
msgstr ""
<<<<<<< HEAD
msgid "Add Group Webhooks and GitLab Enterprise Edition."
msgstr ""
=======
>>>>>>> upstream/master
msgid "Add Kubernetes cluster"
msgstr ""
......@@ -273,9 +281,12 @@ msgstr ""
msgid "An error occurred while making the request."
msgstr ""
<<<<<<< HEAD
msgid "An error occurred while removing approver"
msgstr ""
=======
>>>>>>> upstream/master
msgid "An error occurred while rendering KaTeX"
msgstr ""
......@@ -414,6 +425,7 @@ msgstr ""
msgid "Begin with the selected commit"
msgstr ""
<<<<<<< HEAD
msgid "Billing"
msgstr ""
......@@ -468,6 +480,8 @@ msgstr ""
msgid "BillingPlans|per user"
msgstr ""
=======
>>>>>>> upstream/master
msgid "Branch (%{branch_count})"
msgid_plural "Branches (%{branch_count})"
msgstr[0] ""
......@@ -1052,9 +1066,12 @@ msgstr ""
msgid "ClusterIntegration|properly configured"
msgstr ""
<<<<<<< HEAD
msgid "Collapse"
msgstr ""
=======
>>>>>>> upstream/master
msgid "Comment and resolve discussion"
msgstr ""
......@@ -1454,9 +1471,12 @@ msgstr ""
msgid "Emails"
msgstr ""
<<<<<<< HEAD
msgid "Enable"
msgstr ""
=======
>>>>>>> upstream/master
msgid "Enable Auto DevOps"
msgstr ""
......@@ -1592,6 +1612,7 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
<<<<<<< HEAD
msgid "External Classification Policy Authorization"
msgstr ""
......@@ -1607,6 +1628,8 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
=======
>>>>>>> upstream/master
msgid "Failed Jobs"
msgstr ""
......@@ -1947,6 +1970,7 @@ msgstr ""
msgid "Import repository"
msgstr ""
<<<<<<< HEAD
msgid "Improve Issue boards with GitLab Enterprise Edition."
msgstr ""
......@@ -1956,6 +1980,8 @@ msgstr ""
msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
=======
>>>>>>> upstream/master
msgid "Install Runner on Kubernetes"
msgstr ""
......@@ -2841,9 +2867,12 @@ msgstr ""
msgid "Push to create a project"
msgstr ""
<<<<<<< HEAD
msgid "PushRule|Committer restriction"
msgstr ""
=======
>>>>>>> upstream/master
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
......@@ -3038,6 +3067,7 @@ msgstr ""
msgid "Setup a specific Runner automatically"
msgstr ""
<<<<<<< HEAD
msgid "SharedRunnersMinutesSettings|By resetting the pipeline minutes for this namespace, the currently used minutes will be set to zero."
msgstr ""
......@@ -3047,6 +3077,8 @@ msgstr ""
msgid "SharedRunnersMinutesSettings|Reset used pipeline minutes"
msgstr ""
=======
>>>>>>> upstream/master
msgid "Show command"
msgstr ""
......@@ -3092,9 +3124,12 @@ msgid "Something went wrong when toggling the button"
msgstr ""
msgid "Something went wrong while closing the %{issuable}. Please try again later"
<<<<<<< HEAD
msgstr ""
msgid "Something went wrong while fetching SAST."
=======
>>>>>>> upstream/master
msgstr ""
msgid "Something went wrong while fetching the projects."
......@@ -3667,12 +3702,15 @@ msgstr ""
msgid "Tip:"
msgstr ""
<<<<<<< HEAD
msgid "Title"
msgstr ""
msgid "To view the roadmap, add a planned start or finish date to one of your epics in this group or its subgroups. Only epics in the past 3 months and the next 3 months are shown."
msgstr ""
=======
>>>>>>> upstream/master
msgid "Todo"
msgstr ""
......@@ -3814,12 +3852,15 @@ msgstr ""
msgid "Web IDE"
msgstr ""
<<<<<<< HEAD
msgid "Webhooks allow you to trigger a URL if, for example, new code is pushed or a new issue is created. You can configure webhooks to listen for specific events like pushes, issues or merge requests. Group webhooks will apply to all projects in a group, allowing you to standardize webhook functionality across your entire group."
msgstr ""
msgid "Weight"
msgstr ""
=======
>>>>>>> upstream/master
msgid "Wiki"
msgstr ""
......@@ -3952,6 +3993,9 @@ msgstr ""
msgid "You can also create a project from the command line."
msgstr ""
msgid "You can also create a project from the command line."
msgstr ""
msgid "You can also star a label to make it a priority label."
msgstr ""
......@@ -4045,6 +4089,7 @@ msgstr ""
msgid "branch name"
msgstr ""
<<<<<<< HEAD
msgid "by"
msgstr ""
......@@ -4111,6 +4156,11 @@ msgstr ""
msgid "commit"
msgstr ""
=======
msgid "command line instructions"
msgstr ""
>>>>>>> upstream/master
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
......
......@@ -34,5 +34,6 @@ FactoryBot.define do
factory :clusters_applications_ingress, class: Clusters::Applications::Ingress
factory :clusters_applications_prometheus, class: Clusters::Applications::Prometheus
factory :clusters_applications_runner, class: Clusters::Applications::Runner
end
end
......@@ -38,11 +38,9 @@ describe('Applications', () => {
expect(vm.$el.querySelector('.js-cluster-application-row-prometheus')).toBeDefined();
});
/* * /
it('renders a row for GitLab Runner', () => {
expect(vm.$el.querySelector('.js-cluster-application-row-runner')).toBeDefined();
});
/* */
});
describe('Ingress application', () => {
......
......@@ -393,10 +393,7 @@ describe Gitlab::Git::Commit, seed_helper: true do
end
end
describe '.extract_signature' do
subject { described_class.extract_signature(repository, commit_id) }
shared_examples '.extract_signature' do
shared_examples 'extracting commit signature' do
context 'when the commit is signed' do
let(:commit_id) { '0b4bc9a49b562e85de7cc9e834518ea6828729b9' }
......@@ -462,12 +459,45 @@ describe Gitlab::Git::Commit, seed_helper: true do
end
end
describe '.extract_signature_lazily' do
shared_examples 'loading signatures in batch once' do
it 'fetches signatures in batch once' do
commit_ids = %w[0b4bc9a49b562e85de7cc9e834518ea6828729b9 4b4918a572fa86f9771e5ba40fbd48e1eb03e2c6]
signatures = commit_ids.map do |commit_id|
described_class.extract_signature_lazily(repository, commit_id)
end
expect(described_class).to receive(:batch_signature_extraction)
.with(repository, commit_ids)
.once
.and_return({})
2.times { signatures.each(&:itself) }
end
end
subject { described_class.extract_signature_lazily(repository, commit_id).itself }
context 'with Gitaly extract_commit_signature_in_batch feature enabled' do
it_behaves_like 'extracting commit signature'
it_behaves_like 'loading signatures in batch once'
end
context 'with Gitaly extract_commit_signature_in_batch feature disabled', :disable_gitaly do
it_behaves_like 'extracting commit signature'
it_behaves_like 'loading signatures in batch once'
end
end
describe '.extract_signature' do
subject { described_class.extract_signature(repository, commit_id) }
context 'with gitaly' do
it_behaves_like '.extract_signature'
it_behaves_like 'extracting commit signature'
end
context 'without gitaly', :skip_gitaly_mock do
it_behaves_like '.extract_signature'
context 'without gitaly', :disable_gitaly do
it_behaves_like 'extracting commit signature'
end
end
end
......
......@@ -38,7 +38,7 @@ describe Gitlab::Gpg::Commit do
end
before do
allow(Gitlab::Git::Commit).to receive(:extract_signature)
allow(Gitlab::Git::Commit).to receive(:extract_signature_lazily)
.with(Gitlab::Git::Repository, commit_sha)
.and_return(
[
......@@ -101,7 +101,7 @@ describe Gitlab::Gpg::Commit do
end
before do
allow(Gitlab::Git::Commit).to receive(:extract_signature)
allow(Gitlab::Git::Commit).to receive(:extract_signature_lazily)
.with(Gitlab::Git::Repository, commit_sha)
.and_return(
[
......@@ -140,7 +140,7 @@ describe Gitlab::Gpg::Commit do
end
before do
allow(Gitlab::Git::Commit).to receive(:extract_signature)
allow(Gitlab::Git::Commit).to receive(:extract_signature_lazily)
.with(Gitlab::Git::Repository, commit_sha)
.and_return(
[
......@@ -175,7 +175,7 @@ describe Gitlab::Gpg::Commit do
end
before do
allow(Gitlab::Git::Commit).to receive(:extract_signature)
allow(Gitlab::Git::Commit).to receive(:extract_signature_lazily)
.with(Gitlab::Git::Repository, commit_sha)
.and_return(
[
......@@ -211,7 +211,7 @@ describe Gitlab::Gpg::Commit do
end
before do
allow(Gitlab::Git::Commit).to receive(:extract_signature)
allow(Gitlab::Git::Commit).to receive(:extract_signature_lazily)
.with(Gitlab::Git::Repository, commit_sha)
.and_return(
[
......@@ -241,7 +241,7 @@ describe Gitlab::Gpg::Commit do
let!(:commit) { create :commit, project: project, sha: commit_sha }
before do
allow(Gitlab::Git::Commit).to receive(:extract_signature)
allow(Gitlab::Git::Commit).to receive(:extract_signature_lazily)
.with(Gitlab::Git::Repository, commit_sha)
.and_return(
[
......
......@@ -26,7 +26,7 @@ RSpec.describe Gitlab::Gpg::InvalidGpgSignatureUpdater do
before do
allow_any_instance_of(Project).to receive(:commit).and_return(commit)
allow(Gitlab::Git::Commit).to receive(:extract_signature)
allow(Gitlab::Git::Commit).to receive(:extract_signature_lazily)
.with(Gitlab::Git::Repository, commit_sha)
.and_return(signature)
end
......
require 'spec_helper'
describe Gitlab::Kubernetes::ConfigMap do
let(:kubeclient) { double('kubernetes client') }
let(:application) { create(:clusters_applications_prometheus) }
let(:config_map) { described_class.new(application.name, application.values) }
let(:namespace) { Gitlab::Kubernetes::Helm::NAMESPACE }
let(:metadata) do
{
name: "values-content-configuration-#{application.name}",
namespace: namespace,
labels: { name: "values-content-configuration-#{application.name}" }
}
end
describe '#generate' do
let(:resource) { ::Kubeclient::Resource.new(metadata: metadata, data: { values: application.values }) }
subject { config_map.generate }
it 'should build a Kubeclient Resource' do
is_expected.to eq(resource)
end
end
end
......@@ -5,14 +5,21 @@ describe Gitlab::Kubernetes::Helm::Api do
let(:helm) { described_class.new(client) }
let(:gitlab_namespace) { Gitlab::Kubernetes::Helm::NAMESPACE }
let(:namespace) { Gitlab::Kubernetes::Namespace.new(gitlab_namespace, client) }
let(:install_helm) { true }
let(:chart) { 'stable/a_chart' }
let(:application_name) { 'app_name' }
let(:command) { Gitlab::Kubernetes::Helm::InstallCommand.new(application_name, install_helm: install_helm, chart: chart) }
let(:application) { create(:clusters_applications_prometheus) }
let(:command) do
Gitlab::Kubernetes::Helm::InstallCommand.new(
application.name,
chart: application.chart,
values: application.values
)
end
subject { helm }
before do
allow(Gitlab::Kubernetes::Namespace).to receive(:new).with(gitlab_namespace, client).and_return(namespace)
allow(client).to receive(:create_config_map)
end
describe '#initialize' do
......@@ -26,6 +33,7 @@ describe Gitlab::Kubernetes::Helm::Api do
describe '#install' do
before do
allow(client).to receive(:create_pod).and_return(nil)
allow(client).to receive(:create_config_map).and_return(nil)
allow(namespace).to receive(:ensure_exists!).once
end
......@@ -35,6 +43,16 @@ describe Gitlab::Kubernetes::Helm::Api do
subject.install(command)
end
context 'with a ConfigMap' do
let(:resource) { Gitlab::Kubernetes::ConfigMap.new(application.name, application.values).generate }
it 'creates a ConfigMap on kubeclient' do
expect(client).to receive(:create_config_map).with(resource).once
subject.install(command)
end
end
end
describe '#installation_status' do
......
require 'spec_helper'
describe Gitlab::Kubernetes::Helm::BaseCommand do
let(:application) { create(:clusters_applications_helm) }
let(:base_command) { described_class.new(application.name) }
describe '#generate_script' do
let(:helm_version) { Gitlab::Kubernetes::Helm::HELM_VERSION }
let(:command) do
<<~HEREDOC
set -eo pipefail
apk add -U ca-certificates openssl >/dev/null
wget -q -O - https://kubernetes-helm.storage.googleapis.com/helm-v#{helm_version}-linux-amd64.tar.gz | tar zxC /tmp >/dev/null
mv /tmp/linux-amd64/helm /usr/bin/
HEREDOC
end
subject { base_command.generate_script }
it 'should return a command that prepares the environment for helm-cli' do
expect(subject).to eq(command)
end
end
describe '#pod_resource' do
subject { base_command.pod_resource }
it 'should returns a kubeclient resoure with pod content for application' do
is_expected.to be_an_instance_of ::Kubeclient::Resource
end
end
describe '#config_map?' do
subject { base_command.config_map? }
it { is_expected.to be_falsy }
end
describe '#pod_name' do
subject { base_command.pod_name }
it { is_expected.to eq('install-helm') }
end
end
require 'spec_helper'
describe Gitlab::Kubernetes::Helm::InitCommand do
let(:application) { create(:clusters_applications_helm) }
let(:init_command) { described_class.new(application.name) }
describe '#generate_script' do
let(:command) do
<<~MSG.chomp
set -eo pipefail
apk add -U ca-certificates openssl >/dev/null
wget -q -O - https://kubernetes-helm.storage.googleapis.com/helm-v2.7.0-linux-amd64.tar.gz | tar zxC /tmp >/dev/null
mv /tmp/linux-amd64/helm /usr/bin/
helm init >/dev/null
MSG
end
subject { init_command.generate_script }
it 'should return the appropriate command' do
is_expected.to eq(command)
end
end
end
require 'rails_helper'
describe Gitlab::Kubernetes::Helm::InstallCommand do
let(:prometheus) { create(:clusters_applications_prometheus) }
let(:application) { create(:clusters_applications_prometheus) }
let(:namespace) { Gitlab::Kubernetes::Helm::NAMESPACE }
describe "#initialize" do
context "With all the params" do
subject { described_class.new(prometheus.name, install_helm: true, chart: prometheus.chart, chart_values_file: prometheus.chart_values_file) }
it 'should assign all parameters' do
expect(subject.name).to eq(prometheus.name)
expect(subject.install_helm).to be_truthy
expect(subject.chart).to eq(prometheus.chart)
expect(subject.chart_values_file).to eq("#{Rails.root}/vendor/prometheus/values.yaml")
end
end
context 'when install_helm is not set' do
subject { described_class.new(prometheus.name, chart: prometheus.chart, chart_values_file: true) }
it 'should set install_helm as false' do
expect(subject.install_helm).to be_falsy
end
let(:install_command) do
described_class.new(
application.name,
chart: application.chart,
values: application.values
)
end
context 'when chart is not set' do
subject { described_class.new(prometheus.name, install_helm: true) }
it 'should set chart as nil' do
expect(subject.chart).to be_falsy
end
end
context 'when chart_values_file is not set' do
subject { described_class.new(prometheus.name, install_helm: true, chart: prometheus.chart) }
it 'should set chart_values_file as nil' do
expect(subject.chart_values_file).to be_falsy
end
end
end
describe "#generate_script" do
let(:install_command) { described_class.new(prometheus.name, install_helm: install_helm) }
let(:client) { double('kubernetes client') }
let(:namespace) { Gitlab::Kubernetes::Namespace.new(Gitlab::Kubernetes::Helm::NAMESPACE, client) }
subject { install_command.send(:generate_script, namespace.name) }
context 'when install helm is true' do
let(:install_helm) { true }
describe '#generate_script' do
let(:command) do
<<~MSG
set -eo pipefail
apk add -U ca-certificates openssl >/dev/null
wget -q -O - https://kubernetes-helm.storage.googleapis.com/helm-v2.7.0-linux-amd64.tar.gz | tar zxC /tmp >/dev/null
mv /tmp/linux-amd64/helm /usr/bin/
helm init >/dev/null
helm init --client-only >/dev/null
helm install #{application.chart} --name #{application.name} --namespace #{namespace} -f /data/helm/#{application.name}/config/values.yaml >/dev/null
MSG
end
subject { install_command.generate_script }
it 'should return appropriate command' do
is_expected.to eq(command)
end
context 'with an application with a repository' do
let(:ci_runner) { create(:ci_runner) }
let(:application) { create(:clusters_applications_runner, runner: ci_runner) }
let(:install_command) do
described_class.new(
application.name,
chart: application.chart,
values: application.values,
repository: application.repository
)
end
context 'when install helm is false' do
let(:install_helm) { false }
let(:command) do
<<~MSG
set -eo pipefail
apk add -U ca-certificates openssl >/dev/null
wget -q -O - https://kubernetes-helm.storage.googleapis.com/helm-v2.7.0-linux-amd64.tar.gz | tar zxC /tmp >/dev/null
mv /tmp/linux-amd64/helm /usr/bin/
helm init --client-only >/dev/null
helm repo add #{application.name} #{application.repository}
helm install #{application.chart} --name #{application.name} --namespace #{namespace} -f /data/helm/#{application.name}/config/values.yaml >/dev/null
MSG
end
......@@ -81,50 +58,29 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
is_expected.to eq(command)
end
end
end
context 'when chart is present' do
let(:install_command) { described_class.new(prometheus.name, chart: prometheus.chart) }
let(:command) do
<<~MSG.chomp
set -eo pipefail
apk add -U ca-certificates openssl >/dev/null
wget -q -O - https://kubernetes-helm.storage.googleapis.com/helm-v2.7.0-linux-amd64.tar.gz | tar zxC /tmp >/dev/null
mv /tmp/linux-amd64/helm /usr/bin/
describe '#config_map?' do
subject { install_command.config_map? }
helm init --client-only >/dev/null
helm install #{prometheus.chart} --name #{prometheus.name} --namespace #{namespace.name} >/dev/null
MSG
it { is_expected.to be_truthy }
end
it 'should return appropriate command' do
is_expected.to eq(command)
end
describe '#config_map_resource' do
let(:metadata) do
{
name: "values-content-configuration-#{application.name}",
namespace: namespace,
labels: { name: "values-content-configuration-#{application.name}" }
}
end
context 'when chart values file is present' do
let(:install_command) { described_class.new(prometheus.name, chart: prometheus.chart, chart_values_file: prometheus.chart_values_file) }
let(:command) do
<<~MSG.chomp
set -eo pipefail
apk add -U ca-certificates openssl >/dev/null
wget -q -O - https://kubernetes-helm.storage.googleapis.com/helm-v2.7.0-linux-amd64.tar.gz | tar zxC /tmp >/dev/null
mv /tmp/linux-amd64/helm /usr/bin/
let(:resource) { ::Kubeclient::Resource.new(metadata: metadata, data: { values: application.values }) }
helm init --client-only >/dev/null
helm install #{prometheus.chart} --name #{prometheus.name} --namespace #{namespace.name} -f /data/helm/#{prometheus.name}/config/values.yaml >/dev/null
MSG
end
subject { install_command.config_map_resource }
it 'should return appropriate command' do
is_expected.to eq(command)
end
end
it 'returns a KubeClient resource with config map content for the application' do
is_expected.to eq(resource)
end
describe "#pod_name" do
let(:install_command) { described_class.new(prometheus.name, install_helm: true, chart: prometheus.chart, chart_values_file: true) }
subject { install_command.send(:pod_name) }
it { is_expected.to eq('install-prometheus') }
end
end
......@@ -5,13 +5,9 @@ describe Gitlab::Kubernetes::Helm::Pod do
let(:cluster) { create(:cluster) }
let(:app) { create(:clusters_applications_prometheus, cluster: cluster) }
let(:command) { app.install_command }
let(:client) { double('kubernetes client') }
let(:namespace) { Gitlab::Kubernetes::Namespace.new(Gitlab::Kubernetes::Helm::NAMESPACE, client) }
subject { described_class.new(command, namespace.name, client) }
let(:namespace) { Gitlab::Kubernetes::Helm::NAMESPACE }
before do
allow(client).to receive(:create_config_map).and_return(nil)
end
subject { described_class.new(command, namespace) }
shared_examples 'helm pod' do
it 'should generate a Kubeclient::Resource' do
......@@ -47,7 +43,7 @@ describe Gitlab::Kubernetes::Helm::Pod do
end
end
context 'with a configuration file' do
context 'with a install command' do
it_behaves_like 'helm pod'
it 'should include volumes for the container' do
......@@ -62,14 +58,14 @@ describe Gitlab::Kubernetes::Helm::Pod do
end
it 'should mount configMap specification in the volume' do
spec = subject.generate.spec
expect(spec.volumes.first.configMap['name']).to eq("values-content-configuration-#{app.name}")
expect(spec.volumes.first.configMap['items'].first['key']).to eq('values')
expect(spec.volumes.first.configMap['items'].first['path']).to eq('values.yaml')
volume = subject.generate.spec.volumes.first
expect(volume.configMap['name']).to eq("values-content-configuration-#{app.name}")
expect(volume.configMap['items'].first['key']).to eq('values')
expect(volume.configMap['items'].first['path']).to eq('values.yaml')
end
end
context 'without a configuration file' do
context 'with a init command' do
let(:app) { create(:clusters_applications_helm, cluster: cluster) }
it_behaves_like 'helm pod'
......
require 'rails_helper'
describe Clusters::Applications::Helm do
it { is_expected.to belong_to(:cluster) }
it { is_expected.to validate_presence_of(:cluster) }
describe '#name' do
it 'is .application_name' do
expect(subject.name).to eq(described_class.application_name)
end
it 'is recorded in Clusters::Cluster::APPLICATIONS' do
expect(Clusters::Cluster::APPLICATIONS[subject.name]).to eq(described_class)
end
end
describe '#version' do
it 'defaults to Gitlab::Kubernetes::Helm::HELM_VERSION' do
expect(subject.version).to eq(Gitlab::Kubernetes::Helm::HELM_VERSION)
end
end
describe '#status' do
let(:cluster) { create(:cluster) }
subject { described_class.new(cluster: cluster) }
it 'defaults to :not_installable' do
expect(subject.status_name).to be(:not_installable)
end
context 'when platform kubernetes is defined' do
let(:cluster) { create(:cluster, :provided_by_gcp) }
it 'defaults to :installable' do
expect(subject.status_name).to be(:installable)
end
end
end
include_examples 'cluster application core specs', :clusters_applications_helm
describe '#install_command' do
it 'has all the needed information' do
expect(subject.install_command).to have_attributes(name: subject.name, install_helm: true)
end
end
let(:helm) { create(:clusters_applications_helm) }
describe 'status state machine' do
describe '#make_installing' do
subject { create(:clusters_applications_helm, :scheduled) }
subject { helm.install_command }
it 'is installing' do
subject.make_installing!
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::InitCommand) }
expect(subject).to be_installing
end
end
describe '#make_installed' do
subject { create(:clusters_applications_helm, :installing) }
it 'is installed' do
subject.make_installed
expect(subject).to be_installed
end
end
describe '#make_errored' do
subject { create(:clusters_applications_helm, :installing) }
let(:reason) { 'some errors' }
it 'is errored' do
subject.make_errored(reason)
expect(subject).to be_errored
expect(subject.status_reason).to eq(reason)
end
end
describe '#make_scheduled' do
subject { create(:clusters_applications_helm, :installable) }
it 'is scheduled' do
subject.make_scheduled
expect(subject).to be_scheduled
end
describe 'when was errored' do
subject { create(:clusters_applications_helm, :errored) }
it 'clears #status_reason' do
expect(subject.status_reason).not_to be_nil
subject.make_scheduled!
expect(subject.status_reason).to be_nil
end
end
it 'should be initialized with 1 arguments' do
expect(subject.name).to eq('helm')
end
end
end
require 'rails_helper'
describe Clusters::Applications::Ingress do
it { is_expected.to belong_to(:cluster) }
it { is_expected.to validate_presence_of(:cluster) }
let(:ingress) { create(:clusters_applications_ingress) }
include_examples 'cluster application core specs', :clusters_applications_ingress
include_examples 'cluster application status specs', :cluster_application_ingress
before do
allow(ClusterWaitForIngressIpAddressWorker).to receive(:perform_in)
allow(ClusterWaitForIngressIpAddressWorker).to receive(:perform_async)
end
include_examples 'cluster application specs', described_class
describe '#make_installed!' do
before do
application.make_installed!
......@@ -52,4 +52,27 @@ describe Clusters::Applications::Ingress do
end
end
end
describe '#install_command' do
subject { ingress.install_command }
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::InstallCommand) }
it 'should be initialized with ingress arguments' do
expect(subject.name).to eq('ingress')
expect(subject.chart).to eq('stable/nginx-ingress')
expect(subject.values).to eq(ingress.values)
end
end
describe '#values' do
subject { ingress.values }
it 'should include ingress valid keys' do
is_expected.to include('image')
is_expected.to include('repository')
is_expected.to include('stats')
is_expected.to include('podAnnotations')
end
end
end
require 'rails_helper'
describe Clusters::Applications::Prometheus do
it { is_expected.to belong_to(:cluster) }
it { is_expected.to validate_presence_of(:cluster) }
include_examples 'cluster application specs', described_class
include_examples 'cluster application core specs', :clusters_applications_prometheus
include_examples 'cluster application status specs', :cluster_application_prometheus
describe 'transition to installed' do
let(:project) { create(:project) }
......@@ -24,14 +22,6 @@ describe Clusters::Applications::Prometheus do
end
end
describe "#chart_values_file" do
subject { create(:clusters_applications_prometheus).chart_values_file }
it 'should return chart values file path' do
expect(subject).to eq("#{Rails.root}/vendor/prometheus/values.yaml")
end
end
describe '#proxy_client' do
context 'cluster is nil' do
it 'returns nil' do
......@@ -85,4 +75,33 @@ describe Clusters::Applications::Prometheus do
end
end
end
describe '#install_command' do
let(:kubeclient) { double('kubernetes client') }
let(:prometheus) { create(:clusters_applications_prometheus) }
subject { prometheus.install_command }
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::InstallCommand) }
it 'should be initialized with 3 arguments' do
expect(subject.name).to eq('prometheus')
expect(subject.chart).to eq('stable/prometheus')
expect(subject.values).to eq(prometheus.values)
end
end
describe '#values' do
let(:prometheus) { create(:clusters_applications_prometheus) }
subject { prometheus.values }
it 'should include prometheus valid values' do
is_expected.to include('alertmanager')
is_expected.to include('kubeStateMetrics')
is_expected.to include('nodeExporter')
is_expected.to include('pushgateway')
is_expected.to include('serverFiles')
end
end
end
require 'rails_helper'
describe Clusters::Applications::Runner do
let(:ci_runner) { create(:ci_runner) }
include_examples 'cluster application core specs', :clusters_applications_runner
include_examples 'cluster application status specs', :cluster_application_runner
it { is_expected.to belong_to(:runner) }
describe '#install_command' do
let(:kubeclient) { double('kubernetes client') }
let(:gitlab_runner) { create(:clusters_applications_runner, runner: ci_runner) }
subject { gitlab_runner.install_command }
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::InstallCommand) }
it 'should be initialized with 4 arguments' do
expect(subject.name).to eq('runner')
expect(subject.chart).to eq('runner/gitlab-runner')
expect(subject.repository).to eq('https://charts.gitlab.io')
expect(subject.values).to eq(gitlab_runner.values)
end
end
describe '#values' do
let(:gitlab_runner) { create(:clusters_applications_runner, runner: ci_runner) }
subject { gitlab_runner.values }
it 'should include runner valid values' do
is_expected.to include('concurrent')
is_expected.to include('checkInterval')
is_expected.to include('rbac')
is_expected.to include('runners')
is_expected.to include('resources')
is_expected.to include("runnerToken: #{ci_runner.token}")
is_expected.to include("gitlabUrl: #{Gitlab::Routing.url_helpers.root_url}")
end
context 'without a runner' do
let(:project) { create(:project) }
let(:cluster) { create(:cluster) }
let(:gitlab_runner) { create(:clusters_applications_runner, cluster: cluster) }
before do
cluster.projects << project
end
it 'creates a runner' do
expect do
subject
end.to change { Ci::Runner.count }.by(1)
end
it 'uses the new runner token' do
expect(subject).to include("runnerToken: #{gitlab_runner.reload.runner.token}")
end
it 'assigns the new runner to runner' do
subject
gitlab_runner.reload
expect(gitlab_runner.runner).not_to be_nil
end
end
end
end
......@@ -8,6 +8,7 @@ describe Clusters::Cluster do
it { is_expected.to have_one(:application_helm) }
it { is_expected.to have_one(:application_ingress) }
it { is_expected.to have_one(:application_prometheus) }
it { is_expected.to have_one(:application_runner) }
it { is_expected.to delegate_method(:status).to(:provider) }
it { is_expected.to delegate_method(:status_reason).to(:provider) }
it { is_expected.to delegate_method(:status_name).to(:provider) }
......@@ -224,9 +225,10 @@ describe Clusters::Cluster do
let!(:helm) { create(:clusters_applications_helm, cluster: cluster) }
let!(:ingress) { create(:clusters_applications_ingress, cluster: cluster) }
let!(:prometheus) { create(:clusters_applications_prometheus, cluster: cluster) }
let!(:runner) { create(:clusters_applications_runner, cluster: cluster) }
it 'returns a list of created applications' do
is_expected.to contain_exactly(helm, ingress, prometheus)
is_expected.to contain_exactly(helm, ingress, prometheus, runner)
end
end
end
......
......@@ -368,7 +368,9 @@ describe CommitStatus do
'rspec:windows 0 : / 1' => 'rspec:windows',
'rspec:windows 0 : / 1 name' => 'rspec:windows name',
'0 1 name ruby' => 'name ruby',
'0 :/ 1 name ruby' => 'name ruby'
'0 :/ 1 name ruby' => 'name ruby',
'golang test 1.8' => 'golang test',
'1.9 golang test' => 'golang test'
}
tests.each do |name, group_name|
......
......@@ -15,8 +15,8 @@ describe MergeRequests::BuildService do
let(:target_branch) { 'master' }
let(:merge_request) { service.execute }
let(:compare) { double(:compare, commits: commits) }
let(:commit_1) { double(:commit_1, safe_message: "Initial commit\n\nCreate the app") }
let(:commit_2) { double(:commit_2, safe_message: 'This is a bad commit message!') }
let(:commit_1) { double(:commit_1, sha: 'f00ba7', safe_message: "Initial commit\n\nCreate the app") }
let(:commit_2) { double(:commit_2, sha: 'f00ba7', safe_message: 'This is a bad commit message!') }
let(:commits) { nil }
let(:service) do
......
shared_examples 'cluster application specs' do
let(:factory_name) { described_class.to_s.downcase.gsub("::", "_") }
shared_examples 'cluster application core specs' do |application_name|
it { is_expected.to belong_to(:cluster) }
it { is_expected.to validate_presence_of(:cluster) }
describe '#name' do
it 'is .application_name' do
......@@ -11,45 +12,9 @@ shared_examples 'cluster application specs' do
end
end
describe '#status' do
let(:cluster) { create(:cluster, :provided_by_gcp) }
subject { described_class.new(cluster: cluster) }
it 'defaults to :not_installable' do
expect(subject.status_name).to be(:not_installable)
end
context 'when application helm is scheduled' do
before do
create(factory_name, :scheduled, cluster: cluster)
end
it 'defaults to :not_installable' do
expect(subject.status_name).to be(:not_installable)
end
end
context 'when application helm is installed' do
before do
create(:clusters_applications_helm, :installed, cluster: cluster)
end
it 'defaults to :installable' do
expect(subject.status_name).to be(:installable)
end
end
end
describe '#install_command' do
it 'has all the needed information' do
expect(subject.install_command).to have_attributes(name: subject.name, install_helm: false)
end
end
describe 'status state machine' do
describe '#make_installing' do
subject { create(factory_name, :scheduled) }
subject { create(application_name, :scheduled) }
it 'is installing' do
subject.make_installing!
......@@ -59,7 +24,7 @@ shared_examples 'cluster application specs' do
end
describe '#make_installed' do
subject { create(factory_name, :installing) }
subject { create(application_name, :installing) }
it 'is installed' do
subject.make_installed
......@@ -69,7 +34,7 @@ shared_examples 'cluster application specs' do
end
describe '#make_errored' do
subject { create(factory_name, :installing) }
subject { create(application_name, :installing) }
let(:reason) { 'some errors' }
it 'is errored' do
......@@ -81,7 +46,7 @@ shared_examples 'cluster application specs' do
end
describe '#make_scheduled' do
subject { create(factory_name, :installable) }
subject { create(application_name, :installable) }
it 'is scheduled' do
subject.make_scheduled
......@@ -90,7 +55,7 @@ shared_examples 'cluster application specs' do
end
describe 'when was errored' do
subject { create(factory_name, :errored) }
subject { create(application_name, :errored) }
it 'clears #status_reason' do
expect(subject.status_reason).not_to be_nil
......
shared_examples 'cluster application status specs' do |application_name|
describe '#status' do
let(:cluster) { create(:cluster, :provided_by_gcp) }
subject { described_class.new(cluster: cluster) }
it 'sets a default status' do
expect(subject.status_name).to be(:not_installable)
end
context 'when application helm is scheduled' do
before do
create(:clusters_applications_helm, :scheduled, cluster: cluster)
end
it 'defaults to :not_installable' do
expect(subject.status_name).to be(:not_installable)
end
end
context 'when application is scheduled' do
before do
create(:clusters_applications_helm, :installed, cluster: cluster)
end
it 'sets a default status' do
expect(subject.status_name).to be(:installable)
end
end
end
end
## Configure the maximum number of concurrent jobs
## - Documentation: https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-global-section
## - Default value: 10
## - Currently don't support auto-scaling.
concurrent: 4
## Defines in seconds how often to check GitLab for a new builds
## - Documentation: https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-global-section
## - Default value: 3
checkInterval: 3
## For RBAC support
rbac:
create: false
clusterWideAccess: false
## Configuration for the Pods that that the runner launches for each new job
##
runners:
image: ubuntu:16.04
privileged: false
builds: {}
services: {}
helpers: {}
resources: {}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment