Commit 0cd76190 authored by Thong Kuah's avatar Thong Kuah

Lock helm charts to the VERSION already specified for each application.

Fix up VERSION for each of the applications
* There is no 0.0.1 helm version for jupyterhub. Use the latest version instead
* `:nginx` is not a valid chart version. Lock the ingress application GitLab installs to the latest chart version.
* Use the latest gitlab-runner chart to prevent GitLab installing older versions when users have been installing the lastest version

Always install from the VERSION and not the database `version` column.
This should fix cases like https://gitlab.com/gitlab-org/gitlab-ee/issues/6795 in
the instances where an install command failed previously, which locked the version
in the database to an older version.

Also, ensure that the version column is updated to the version we are
installing.

Add specs to show how previously failed appplications will be handled when the helm installation is run again

Add changelog entry
parent b690c268
module Clusters module Clusters
module Applications module Applications
class Ingress < ActiveRecord::Base class Ingress < ActiveRecord::Base
VERSION = '0.23.0'.freeze
self.table_name = 'clusters_applications_ingress' self.table_name = 'clusters_applications_ingress'
include ::Clusters::Concerns::ApplicationCore include ::Clusters::Concerns::ApplicationCore
include ::Clusters::Concerns::ApplicationStatus include ::Clusters::Concerns::ApplicationStatus
include ::Clusters::Concerns::ApplicationVersion
include ::Clusters::Concerns::ApplicationData include ::Clusters::Concerns::ApplicationData
include AfterCommitQueue include AfterCommitQueue
default_value_for :ingress_type, :nginx default_value_for :ingress_type, :nginx
default_value_for :version, :nginx default_value_for :version, VERSION
enum ingress_type: { enum ingress_type: {
nginx: 1 nginx: 1
...@@ -33,6 +36,7 @@ module Clusters ...@@ -33,6 +36,7 @@ module Clusters
def install_command def install_command
Gitlab::Kubernetes::Helm::InstallCommand.new( Gitlab::Kubernetes::Helm::InstallCommand.new(
name, name,
version: VERSION,
chart: chart, chart: chart,
values: values values: values
) )
......
module Clusters module Clusters
module Applications module Applications
class Jupyter < ActiveRecord::Base class Jupyter < ActiveRecord::Base
VERSION = '0.0.1'.freeze VERSION = 'v0.6'.freeze
self.table_name = 'clusters_applications_jupyter' self.table_name = 'clusters_applications_jupyter'
include ::Clusters::Concerns::ApplicationCore include ::Clusters::Concerns::ApplicationCore
include ::Clusters::Concerns::ApplicationStatus include ::Clusters::Concerns::ApplicationStatus
include ::Clusters::Concerns::ApplicationVersion
include ::Clusters::Concerns::ApplicationData include ::Clusters::Concerns::ApplicationData
belongs_to :oauth_application, class_name: 'Doorkeeper::Application' belongs_to :oauth_application, class_name: 'Doorkeeper::Application'
...@@ -36,6 +37,7 @@ module Clusters ...@@ -36,6 +37,7 @@ module Clusters
def install_command def install_command
Gitlab::Kubernetes::Helm::InstallCommand.new( Gitlab::Kubernetes::Helm::InstallCommand.new(
name, name,
version: VERSION,
chart: chart, chart: chart,
values: values, values: values,
repository: repository repository: repository
......
...@@ -9,6 +9,7 @@ module Clusters ...@@ -9,6 +9,7 @@ module Clusters
include ::Clusters::Concerns::ApplicationCore include ::Clusters::Concerns::ApplicationCore
include ::Clusters::Concerns::ApplicationStatus include ::Clusters::Concerns::ApplicationStatus
include ::Clusters::Concerns::ApplicationVersion
include ::Clusters::Concerns::ApplicationData include ::Clusters::Concerns::ApplicationData
default_value_for :version, VERSION default_value_for :version, VERSION
...@@ -44,8 +45,8 @@ module Clusters ...@@ -44,8 +45,8 @@ module Clusters
def install_command def install_command
Gitlab::Kubernetes::Helm::InstallCommand.new( Gitlab::Kubernetes::Helm::InstallCommand.new(
name, name,
version: VERSION,
chart: chart, chart: chart,
version: version,
values: values values: values
) )
end end
......
module Clusters module Clusters
module Applications module Applications
class Runner < ActiveRecord::Base class Runner < ActiveRecord::Base
VERSION = '0.1.13'.freeze VERSION = '0.1.31'.freeze
self.table_name = 'clusters_applications_runners' self.table_name = 'clusters_applications_runners'
include ::Clusters::Concerns::ApplicationCore include ::Clusters::Concerns::ApplicationCore
include ::Clusters::Concerns::ApplicationStatus include ::Clusters::Concerns::ApplicationStatus
include ::Clusters::Concerns::ApplicationVersion
include ::Clusters::Concerns::ApplicationData include ::Clusters::Concerns::ApplicationData
belongs_to :runner, class_name: 'Ci::Runner', foreign_key: :runner_id belongs_to :runner, class_name: 'Ci::Runner', foreign_key: :runner_id
...@@ -29,6 +30,7 @@ module Clusters ...@@ -29,6 +30,7 @@ module Clusters
def install_command def install_command
Gitlab::Kubernetes::Helm::InstallCommand.new( Gitlab::Kubernetes::Helm::InstallCommand.new(
name, name,
version: VERSION,
chart: chart, chart: chart,
values: values, values: values,
repository: repository repository: repository
......
# frozen_string_literal: true
module Clusters
module Concerns
module ApplicationVersion
extend ActiveSupport::Concern
included do
state_machine :status do
after_transition any => [:installing] do |application|
application.update(version: application.class.const_get(:VERSION))
end
end
end
end
end
end
---
title: Chart versions for applications installed by one click install buttons should
be version locked
merge_request: 20765
author:
type: fixed
...@@ -14,7 +14,7 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do ...@@ -14,7 +14,7 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
let(:commands) do let(:commands) do
<<~EOS <<~EOS
helm init --client-only >/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 helm install #{application.chart} --name #{application.name} --version #{application.version} --namespace #{namespace} -f /data/helm/#{application.name}/config/values.yaml >/dev/null
EOS EOS
end end
end end
...@@ -42,7 +42,7 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do ...@@ -42,7 +42,7 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
<<~EOS <<~EOS
helm init --client-only >/dev/null helm init --client-only >/dev/null
helm repo add #{application.name} #{application.repository} 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 helm install #{application.chart} --name #{application.name} --version #{application.version} --namespace #{namespace} -f /data/helm/#{application.name}/config/values.yaml >/dev/null
EOS EOS
end end
end end
...@@ -56,7 +56,7 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do ...@@ -56,7 +56,7 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
<<~EOS <<~EOS
helm init --client-only >/dev/null helm init --client-only >/dev/null
helm repo add #{application.name} #{application.repository} 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 helm install #{application.chart} --name #{application.name} --version #{application.version} --namespace #{namespace} -f /data/helm/#{application.name}/config/values.yaml >/dev/null
EOS EOS
end end
end end
......
...@@ -23,6 +23,20 @@ describe Clusters::Applications::Ingress do ...@@ -23,6 +23,20 @@ describe Clusters::Applications::Ingress do
it { is_expected.to contain_exactly(cluster) } it { is_expected.to contain_exactly(cluster) }
end end
describe '#make_installing!' do
before do
application.make_installing!
end
context 'application install previously errored with older version' do
let(:application) { create(:clusters_applications_ingress, :scheduled, version: '0.22.0') }
it 'updates the application version' do
expect(application.reload.version).to eq('0.23.0')
end
end
end
describe '#make_installed!' do describe '#make_installed!' do
before do before do
application.make_installed! application.make_installed!
...@@ -73,9 +87,17 @@ describe Clusters::Applications::Ingress do ...@@ -73,9 +87,17 @@ describe Clusters::Applications::Ingress do
it 'should be initialized with ingress arguments' do it 'should be initialized with ingress arguments' do
expect(subject.name).to eq('ingress') expect(subject.name).to eq('ingress')
expect(subject.chart).to eq('stable/nginx-ingress') expect(subject.chart).to eq('stable/nginx-ingress')
expect(subject.version).to be_nil expect(subject.version).to eq('0.23.0')
expect(subject.values).to eq(ingress.values) expect(subject.values).to eq(ingress.values)
end end
context 'application failed to install previously' do
let(:ingress) { create(:clusters_applications_ingress, :errored, version: 'nginx') }
it 'should be initialized with the locked version' do
expect(subject.version).to eq('0.23.0')
end
end
end end
describe '#values' do describe '#values' do
......
...@@ -25,6 +25,20 @@ describe Clusters::Applications::Jupyter do ...@@ -25,6 +25,20 @@ describe Clusters::Applications::Jupyter do
end end
end end
describe '#make_installing!' do
before do
application.make_installing!
end
context 'application install previously errored with older version' do
let(:application) { create(:clusters_applications_jupyter, :scheduled, version: 'v0.5') }
it 'updates the application version' do
expect(application.reload.version).to eq('v0.6')
end
end
end
describe '#install_command' do describe '#install_command' do
let!(:ingress) { create(:clusters_applications_ingress, :installed, external_ip: '127.0.0.1') } let!(:ingress) { create(:clusters_applications_ingress, :installed, external_ip: '127.0.0.1') }
let!(:jupyter) { create(:clusters_applications_jupyter, cluster: ingress.cluster) } let!(:jupyter) { create(:clusters_applications_jupyter, cluster: ingress.cluster) }
...@@ -36,10 +50,18 @@ describe Clusters::Applications::Jupyter do ...@@ -36,10 +50,18 @@ describe Clusters::Applications::Jupyter do
it 'should be initialized with 4 arguments' do it 'should be initialized with 4 arguments' do
expect(subject.name).to eq('jupyter') expect(subject.name).to eq('jupyter')
expect(subject.chart).to eq('jupyter/jupyterhub') expect(subject.chart).to eq('jupyter/jupyterhub')
expect(subject.version).to be_nil expect(subject.version).to eq('v0.6')
expect(subject.repository).to eq('https://jupyterhub.github.io/helm-chart/') expect(subject.repository).to eq('https://jupyterhub.github.io/helm-chart/')
expect(subject.values).to eq(jupyter.values) expect(subject.values).to eq(jupyter.values)
end end
context 'application failed to install previously' do
let(:jupyter) { create(:clusters_applications_jupyter, :errored, version: '0.0.1') }
it 'should be initialized with the locked version' do
expect(subject.version).to eq('v0.6')
end
end
end end
describe '#values' do describe '#values' do
......
...@@ -16,6 +16,20 @@ describe Clusters::Applications::Prometheus do ...@@ -16,6 +16,20 @@ describe Clusters::Applications::Prometheus do
it { is_expected.to contain_exactly(cluster) } it { is_expected.to contain_exactly(cluster) }
end end
describe '#make_installing!' do
before do
application.make_installing!
end
context 'application install previously errored with older version' do
let(:application) { create(:clusters_applications_prometheus, :scheduled, version: '6.7.2') }
it 'updates the application version' do
expect(application.reload.version).to eq('6.7.3')
end
end
end
describe 'transition to installed' do describe 'transition to installed' do
let(:project) { create(:project) } let(:project) { create(:project) }
let(:cluster) { create(:cluster, projects: [project]) } let(:cluster) { create(:cluster, projects: [project]) }
...@@ -155,6 +169,14 @@ describe Clusters::Applications::Prometheus do ...@@ -155,6 +169,14 @@ describe Clusters::Applications::Prometheus do
expect(command.version).to eq('6.7.3') expect(command.version).to eq('6.7.3')
expect(command.values).to eq(prometheus.values) expect(command.values).to eq(prometheus.values)
end end
context 'application failed to install previously' do
let(:prometheus) { create(:clusters_applications_prometheus, :errored, version: '2.0.0') }
it 'should be initialized with the locked version' do
expect(subject.version).to eq('6.7.3')
end
end
end end
describe '#values' do describe '#values' do
......
...@@ -8,6 +8,20 @@ describe Clusters::Applications::Runner do ...@@ -8,6 +8,20 @@ describe Clusters::Applications::Runner do
it { is_expected.to belong_to(:runner) } it { is_expected.to belong_to(:runner) }
describe '#make_installing!' do
before do
application.make_installing!
end
context 'application install previously errored with older version' do
let(:application) { create(:clusters_applications_runner, :scheduled, version: '0.1.30') }
it 'updates the application version' do
expect(application.reload.version).to eq('0.1.31')
end
end
end
describe '.installed' do describe '.installed' do
subject { described_class.installed } subject { described_class.installed }
...@@ -31,10 +45,18 @@ describe Clusters::Applications::Runner do ...@@ -31,10 +45,18 @@ describe Clusters::Applications::Runner do
it 'should be initialized with 4 arguments' do it 'should be initialized with 4 arguments' do
expect(subject.name).to eq('runner') expect(subject.name).to eq('runner')
expect(subject.chart).to eq('runner/gitlab-runner') expect(subject.chart).to eq('runner/gitlab-runner')
expect(subject.version).to be_nil expect(subject.version).to eq('0.1.31')
expect(subject.repository).to eq('https://charts.gitlab.io') expect(subject.repository).to eq('https://charts.gitlab.io')
expect(subject.values).to eq(gitlab_runner.values) expect(subject.values).to eq(gitlab_runner.values)
end end
context 'application failed to install previously' do
let(:gitlab_runner) { create(:clusters_applications_runner, :errored, runner: ci_runner, version: '0.1.13') }
it 'should be initialized with the locked version' do
expect(subject.version).to eq('0.1.31')
end
end
end end
describe '#values' do describe '#values' do
......
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