105 lines
2.9 KiB
Ruby
105 lines
2.9 KiB
Ruby
|
module Gitlab
|
||
|
module Clusters
|
||
|
class Helm
|
||
|
Error = Class.new(StandardError)
|
||
|
HELM_VERSION = '2.7.0'.freeze
|
||
|
NAMESPACE = 'gitlab-managed-apps'.freeze
|
||
|
COMMAND_SCRIPT = <<-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/
|
||
|
helm init ${HELM_INIT_OPTS} >/dev/null
|
||
|
[[ -z "${HELM_COMMAND+x}" ]] || helm ${HELM_COMMAND} >/dev/null
|
||
|
EOS
|
||
|
|
||
|
def initialize(kubeclient)
|
||
|
@kubeclient = kubeclient
|
||
|
end
|
||
|
|
||
|
def init!
|
||
|
ensure_namespace!
|
||
|
@kubeclient.create_pod(pod_resource(OpenStruct.new(name: 'helm')))
|
||
|
end
|
||
|
|
||
|
def install(app)
|
||
|
ensure_namespace!
|
||
|
@kubeclient.create_pod(pod_resource(app))
|
||
|
end
|
||
|
|
||
|
##
|
||
|
# Returns Pod phase
|
||
|
#
|
||
|
# https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase
|
||
|
#
|
||
|
# values: "Pending", "Running", "Succeeded", "Failed", "Unknown"
|
||
|
#
|
||
|
def installation_status(app)
|
||
|
@kubeclient.get_pod(pod_name(app), NAMESPACE).status.phase
|
||
|
end
|
||
|
|
||
|
def installation_log(app)
|
||
|
@kubeclient.get_pod_log(pod_name(app), NAMESPACE).body
|
||
|
end
|
||
|
|
||
|
def delete_installation_pod!(app)
|
||
|
@kubeclient.delete_pod(pod_name(app), NAMESPACE)
|
||
|
end
|
||
|
|
||
|
private
|
||
|
|
||
|
def pod_name(app)
|
||
|
"install-#{app.name}"
|
||
|
end
|
||
|
|
||
|
def pod_resource(app)
|
||
|
labels = { 'gitlab.org/action': 'install', 'gitlab.org/application': app.name }
|
||
|
metadata = { name: pod_name(app), namespace: NAMESPACE, labels: labels }
|
||
|
container = {
|
||
|
name: 'helm',
|
||
|
image: 'alpine:3.6',
|
||
|
env: generate_pod_env(app),
|
||
|
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(app)
|
||
|
env = {
|
||
|
HELM_VERSION: HELM_VERSION,
|
||
|
TILLER_NAMESPACE: NAMESPACE,
|
||
|
COMMAND_SCRIPT: COMMAND_SCRIPT
|
||
|
}
|
||
|
|
||
|
if app.name != 'helm'
|
||
|
env[:HELM_INIT_OPTS] = '--client-only'
|
||
|
env[:HELM_COMMAND] = helm_install_comand(app)
|
||
|
end
|
||
|
|
||
|
env.map { |key, value| { name: key, value: value } }
|
||
|
end
|
||
|
|
||
|
def helm_install_comand(app)
|
||
|
"install #{app.chart} --name #{app.name} --namespace #{NAMESPACE}"
|
||
|
end
|
||
|
|
||
|
def ensure_namespace!
|
||
|
begin
|
||
|
@kubeclient.get_namespace(NAMESPACE)
|
||
|
rescue KubeException => ke
|
||
|
raise ke unless ke.error_code == 404
|
||
|
|
||
|
namespace_resource = ::Kubeclient::Resource.new
|
||
|
namespace_resource.metadata = {}
|
||
|
namespace_resource.metadata.name = NAMESPACE
|
||
|
|
||
|
@kubeclient.create_namespace(namespace_resource)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|