diff options
author | Mayra Cabrera <mcabrera@gitlab.com> | 2017-12-22 20:23:43 +0300 |
---|---|---|
committer | Kamil TrzciĆski <ayufan@ayufan.eu> | 2017-12-22 20:23:43 +0300 |
commit | 0d4548026f3060ca0a8f7aa8d8fc89838bc66130 (patch) | |
tree | c6282c19a6f57b605ae7854a1de0779caaeb24fe /lib | |
parent | 79cbfedf670bfc446b64bb74e36d1c93f3180235 (diff) |
Extend Cluster Applications to allow installation of Prometheus
Diffstat (limited to 'lib')
-rw-r--r-- | lib/gitlab/kubernetes/helm.rb | 90 | ||||
-rw-r--r-- | lib/gitlab/kubernetes/helm/api.rb | 42 | ||||
-rw-r--r-- | lib/gitlab/kubernetes/helm/install_command.rb | 53 | ||||
-rw-r--r-- | lib/gitlab/kubernetes/helm/pod.rb | 69 |
4 files changed, 165 insertions, 89 deletions
diff --git a/lib/gitlab/kubernetes/helm.rb b/lib/gitlab/kubernetes/helm.rb index 407cdefc04d..0f0588b8b23 100644 --- a/lib/gitlab/kubernetes/helm.rb +++ b/lib/gitlab/kubernetes/helm.rb @@ -1,96 +1,8 @@ module Gitlab module Kubernetes - class Helm + module Helm HELM_VERSION = '2.7.0'.freeze NAMESPACE = 'gitlab-managed-apps'.freeze - INSTALL_DEPS = <<-EOS.freeze - 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/ - EOS - - InstallCommand = Struct.new(:name, :install_helm, :chart) do - def pod_name - "install-#{name}" - end - end - - def initialize(kubeclient) - @kubeclient = kubeclient - @namespace = Gitlab::Kubernetes::Namespace.new(NAMESPACE, kubeclient) - end - - def install(command) - @namespace.ensure_exists! - @kubeclient.create_pod(pod_resource(command)) - end - - ## - # Returns Pod phase - # - # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase - # - # values: "Pending", "Running", "Succeeded", "Failed", "Unknown" - # - def installation_status(pod_name) - @kubeclient.get_pod(pod_name, @namespace.name).status.phase - end - - def installation_log(pod_name) - @kubeclient.get_pod_log(pod_name, @namespace.name).body - end - - def delete_installation_pod!(pod_name) - @kubeclient.delete_pod(pod_name, @namespace.name) - end - - private - - def pod_resource(command) - labels = { 'gitlab.org/action': 'install', 'gitlab.org/application': command.name } - metadata = { name: command.pod_name, namespace: @namespace.name, labels: labels } - container = { - name: 'helm', - image: 'alpine:3.6', - env: generate_pod_env(command), - command: %w(/bin/sh), - args: %w(-c $(COMMAND_SCRIPT)) - } - spec = { containers: [container], restartPolicy: 'Never' } - - ::Kubeclient::Resource.new(metadata: metadata, spec: spec) - end - - def generate_pod_env(command) - { - HELM_VERSION: HELM_VERSION, - TILLER_NAMESPACE: @namespace.name, - COMMAND_SCRIPT: generate_script(command) - }.map { |key, value| { name: key, value: value } } - end - - def generate_script(command) - [ - INSTALL_DEPS, - helm_init_command(command), - helm_install_command(command) - ].join("\n") - end - - def helm_init_command(command) - if command.install_helm - 'helm init >/dev/null' - else - 'helm init --client-only >/dev/null' - end - end - - def helm_install_command(command) - return if command.chart.nil? - - "helm install #{command.chart} --name #{command.name} --namespace #{@namespace.name} >/dev/null" - end end end end diff --git a/lib/gitlab/kubernetes/helm/api.rb b/lib/gitlab/kubernetes/helm/api.rb new file mode 100644 index 00000000000..ebd7dc1b100 --- /dev/null +++ b/lib/gitlab/kubernetes/helm/api.rb @@ -0,0 +1,42 @@ +module Gitlab + module Kubernetes + module Helm + class Api + def initialize(kubeclient) + @kubeclient = kubeclient + @namespace = Gitlab::Kubernetes::Namespace.new(Gitlab::Kubernetes::Helm::NAMESPACE, kubeclient) + end + + def install(command) + @namespace.ensure_exists! + @kubeclient.create_pod(pod_resource(command)) + end + + ## + # Returns Pod phase + # + # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase + # + # values: "Pending", "Running", "Succeeded", "Failed", "Unknown" + # + def installation_status(pod_name) + @kubeclient.get_pod(pod_name, @namespace.name).status.phase + end + + def installation_log(pod_name) + @kubeclient.get_pod_log(pod_name, @namespace.name).body + end + + def delete_installation_pod!(pod_name) + @kubeclient.delete_pod(pod_name, @namespace.name) + end + + private + + def pod_resource(command) + Pod.new(command, @namespace.name, @kubeclient).generate + end + end + end + end +end diff --git a/lib/gitlab/kubernetes/helm/install_command.rb b/lib/gitlab/kubernetes/helm/install_command.rb new file mode 100644 index 00000000000..8d8c441a4b1 --- /dev/null +++ b/lib/gitlab/kubernetes/helm/install_command.rb @@ -0,0 +1,53 @@ +module Gitlab + module Kubernetes + module Helm + class InstallCommand + attr_reader :name, :install_helm, :chart, :chart_values_file + + def initialize(name, install_helm: false, chart: false, chart_values_file: false) + @name = name + @install_helm = install_helm + @chart = chart + @chart_values_file = chart_values_file + end + + def pod_name + "install-#{name}" + end + + def generate_script(namespace_name) + [ + install_dps_command, + init_command, + complete_command(namespace_name) + ].join("\n") + 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 + + "helm install #{chart} --name #{name} --namespace #{namespace_name} >/dev/null" + end + + def install_dps_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/ + HEREDOC + end + end + end + end +end diff --git a/lib/gitlab/kubernetes/helm/pod.rb b/lib/gitlab/kubernetes/helm/pod.rb new file mode 100644 index 00000000000..233f6bf6227 --- /dev/null +++ b/lib/gitlab/kubernetes/helm/pod.rb @@ -0,0 +1,69 @@ +module Gitlab + module Kubernetes + module Helm + class Pod + def initialize(command, namespace_name, kubeclient) + @command = command + @namespace_name = namespace_name + @kubeclient = kubeclient + end + + def generate + spec = { containers: [container_specification], restartPolicy: 'Never' } + if command.chart_values_file + generate_config_map + spec['volumes'] = volumes_specification + end + ::Kubeclient::Resource.new(metadata: metadata, spec: spec) + end + + private + + attr_reader :command, :namespace_name, :kubeclient + + 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 + { 'gitlab.org/action': 'install', 'gitlab.org/application': command.name } + end + + def metadata + { name: command.pod_name, namespace: namespace_name, labels: labels } + end + + def volume_mounts_specification + [{ name: 'config-volume', mountPath: '/etc/config' }] + end + + def volumes_specification + [{ name: 'config-volume', configMap: { name: 'values-config' } }] + end + + def generate_pod_env(command) + { + 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 generate_config_map + resource = ::Kubeclient::Resource.new + resource.metadata = { name: 'values-config', namespace: namespace_name } + resource.data = YAML.load_file(command.chart_values_file) + kubeclient.create_config_map(resource) + end + end + end + end +end |