Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Léo-Paul Géneau
gitlab-ce
Commits
1f43d563
Commit
1f43d563
authored
Nov 08, 2017
by
Shinya Maeda
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch '38464-k8s-apps' of
https://gitlab.com/gitlab-org/gitlab-ce
into 38464-k8s-apps
parents
93fe6570
e3b5dfdf
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
163 additions
and
42 deletions
+163
-42
app/models/clusters/applications/helm.rb
app/models/clusters/applications/helm.rb
+4
-0
app/services/clusters/applications/base_helm_service.rb
app/services/clusters/applications/base_helm_service.rb
+4
-0
app/services/clusters/applications/check_installation_progress_service.rb
...sters/applications/check_installation_progress_service.rb
+3
-3
app/services/clusters/applications/install_service.rb
app/services/clusters/applications/install_service.rb
+1
-1
lib/gitlab/kubernetes/helm.rb
lib/gitlab/kubernetes/helm.rb
+42
-35
spec/factories/clusters/applications/helm.rb
spec/factories/clusters/applications/helm.rb
+1
-1
spec/lib/gitlab/kubernetes/helm_spec.rb
spec/lib/gitlab/kubernetes/helm_spec.rb
+100
-0
spec/models/clusters/applications/helm_spec.rb
spec/models/clusters/applications/helm_spec.rb
+6
-0
spec/services/clusters/applications/install_service_spec.rb
spec/services/clusters/applications/install_service_spec.rb
+2
-2
No files found.
app/models/clusters/applications/helm.rb
View file @
1f43d563
...
...
@@ -26,6 +26,10 @@ module Clusters
def
name
self
.
class
.
application_name
end
def
install_command
Gitlab
::
Kubernetes
::
Helm
::
InstallCommand
.
new
(
name
,
true
)
end
end
end
end
app/services/clusters/applications/base_helm_service.rb
View file @
1f43d563
...
...
@@ -20,6 +20,10 @@ module Clusters
def
helm_api
@helm_api
||=
Gitlab
::
Kubernetes
::
Helm
.
new
(
kubeclient
)
end
def
install_command
@install_command
||=
app
.
install_command
end
end
end
end
app/services/clusters/applications/check_installation_progress_service.rb
View file @
1f43d563
...
...
@@ -48,17 +48,17 @@ module Clusters
end
def
remove_installation_pod
helm_api
.
delete_installation_pod!
(
app
)
helm_api
.
delete_installation_pod!
(
install_command
.
pod_name
)
rescue
# no-op
end
def
installation_phase
helm_api
.
installation_status
(
app
)
helm_api
.
installation_status
(
install_command
.
pod_name
)
end
def
installation_errors
helm_api
.
installation_log
(
app
)
helm_api
.
installation_log
(
install_command
.
pod_name
)
end
end
end
...
...
app/services/clusters/applications/install_service.rb
View file @
1f43d563
...
...
@@ -6,7 +6,7 @@ module Clusters
begin
app
.
make_installing!
helm_api
.
install
(
app
)
helm_api
.
install
(
install_command
)
ClusterWaitForAppInstallationWorker
.
perform_in
(
ClusterWaitForAppInstallationWorker
::
INTERVAL
,
app
.
name
,
app
.
id
)
...
...
lib/gitlab/kubernetes/helm.rb
View file @
1f43d563
...
...
@@ -3,27 +3,27 @@ module Gitlab
class
Helm
HELM_VERSION
=
'2.7.0'
.
freeze
NAMESPACE
=
'gitlab-managed-apps'
.
freeze
COMMAND_SCRIPT
=
<<-
EOS
.
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/
helm init ${HELM_INIT_OPTS} >/dev/null
[[ -z "${HELM_COMMAND+x}" ]] || helm ${HELM_COMMAND} >/dev/null
EOS
InstallCommand
=
Struct
.
new
(
:name
,
:install_helm
,
:chart
)
do
def
pod_name
"install-
#{
name
}
"
end
end
def
initialize
(
kubeclient
)
@kubeclient
=
kubeclient
@namespace
=
Namespace
.
new
(
NAMESPACE
,
kubeclient
)
end
def
init!
install
(
OpenStruct
.
new
(
name:
'helm'
))
end
def
install
(
app
)
def
install
(
command
)
@namespace
.
ensure_exists!
@kubeclient
.
create_pod
(
pod_resource
(
app
))
@kubeclient
.
create_pod
(
pod_resource
(
command
))
end
##
...
...
@@ -33,31 +33,27 @@ module Gitlab
#
# values: "Pending", "Running", "Succeeded", "Failed", "Unknown"
#
def
installation_status
(
app
)
@kubeclient
.
get_pod
(
pod_name
(
app
)
,
@namespace
.
name
).
status
.
phase
def
installation_status
(
pod_name
)
@kubeclient
.
get_pod
(
pod_name
,
@namespace
.
name
).
status
.
phase
end
def
installation_log
(
app
)
@kubeclient
.
get_pod_log
(
pod_name
(
app
)
,
@namespace
.
name
).
body
def
installation_log
(
pod_name
)
@kubeclient
.
get_pod_log
(
pod_name
,
@namespace
.
name
).
body
end
def
delete_installation_pod!
(
app
)
@kubeclient
.
delete_pod
(
pod_name
(
app
)
,
@namespace
.
name
)
def
delete_installation_pod!
(
pod_name
)
@kubeclient
.
delete_pod
(
pod_name
,
@namespace
.
name
)
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
.
name
,
labels:
labels
}
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
(
app
),
env:
generate_pod_env
(
command
),
command:
%w(/bin/sh)
,
args:
%w(-c $(COMMAND_SCRIPT))
}
...
...
@@ -66,23 +62,34 @@ module Gitlab
::
Kubeclient
::
Resource
.
new
(
metadata:
metadata
,
spec:
spec
)
end
def
generate_pod_env
(
app
)
env
=
{
def
generate_pod_env
(
command
)
{
HELM_VERSION
:
HELM_VERSION
,
TILLER_NAMESPACE
:
NAMESPACE
,
COMMAND_SCRIPT
:
COMMAND_SCRIPT
}
TILLER_NAMESPACE
:
@namespace
.
name
,
COMMAND_SCRIPT
:
generate_script
(
command
)
}.
map
{
|
key
,
value
|
{
name:
key
,
value:
value
}
}
end
if
app
.
name
!=
'helm'
env
[
:HELM_INIT_OPTS
]
=
'--client-only'
env
[
:HELM_COMMAND
]
=
helm_install_comand
(
app
)
end
def
generate_script
(
command
)
[
INSTALL_DEPS
,
helm_init_command
(
command
),
helm_install_command
(
command
)
].
join
(
"
\n
"
)
end
env
.
map
{
|
key
,
value
|
{
name:
key
,
value:
value
}
}
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_comand
(
app
)
"install
#{
app
.
chart
}
--name
#{
app
.
name
}
--namespace
#{
NAMESPACE
}
"
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
...
...
spec/factories/clusters/applications/helm.rb
View file @
1f43d563
...
...
@@ -3,7 +3,7 @@ FactoryGirl.define do
cluster
factory:
%i(cluster provided_by_gcp)
trait
:not_installable
do
status
-
2
status
(
-
2
)
end
trait
:installable
do
...
...
spec/lib/gitlab/kubernetes/helm_spec.rb
0 → 100644
View file @
1f43d563
require
'spec_helper'
describe
Gitlab
::
Kubernetes
::
Helm
do
let
(
:client
)
{
double
(
'kubernetes client'
)
}
let
(
:helm
)
{
described_class
.
new
(
client
)
}
let
(
:namespace
)
{
Gitlab
::
Kubernetes
::
Namespace
.
new
(
described_class
::
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
,
chart
)
}
subject
{
helm
}
before
do
allow
(
Gitlab
::
Kubernetes
::
Namespace
).
to
receive
(
:new
).
with
(
described_class
::
NAMESPACE
,
client
).
and_return
(
namespace
)
end
describe
'#initialize'
do
it
'creates a namespace object'
do
expect
(
Gitlab
::
Kubernetes
::
Namespace
).
to
receive
(
:new
).
with
(
described_class
::
NAMESPACE
,
client
)
subject
end
end
describe
'#install'
do
before
do
allow
(
client
).
to
receive
(
:create_pod
).
and_return
(
nil
)
allow
(
namespace
).
to
receive
(
:ensure_exists!
).
once
end
it
'ensures the namespace exists before creating the POD'
do
expect
(
namespace
).
to
receive
(
:ensure_exists!
).
once
.
ordered
expect
(
client
).
to
receive
(
:create_pod
).
once
.
ordered
subject
.
install
(
command
)
end
end
describe
'#installation_status'
do
let
(
:phase
)
{
Gitlab
::
Kubernetes
::
Pod
::
RUNNING
}
let
(
:pod
)
{
Kubeclient
::
Resource
.
new
(
status:
{
phase:
phase
})
}
# partial representation
it
'fetches POD phase from kubernetes cluster'
do
expect
(
client
).
to
receive
(
:get_pod
).
with
(
command
.
pod_name
,
described_class
::
NAMESPACE
).
once
.
and_return
(
pod
)
expect
(
subject
.
installation_status
(
command
.
pod_name
)).
to
eq
(
phase
)
end
end
describe
'#installation_log'
do
let
(
:log
)
{
'some output'
}
let
(
:response
)
{
RestClient
::
Response
.
new
(
log
)
}
it
'fetches POD phase from kubernetes cluster'
do
expect
(
client
).
to
receive
(
:get_pod_log
).
with
(
command
.
pod_name
,
described_class
::
NAMESPACE
).
once
.
and_return
(
response
)
expect
(
subject
.
installation_log
(
command
.
pod_name
)).
to
eq
(
log
)
end
end
describe
'#delete_installation_pod!'
do
it
'deletes the POD from kubernetes cluster'
do
expect
(
client
).
to
receive
(
:delete_pod
).
with
(
command
.
pod_name
,
described_class
::
NAMESPACE
).
once
subject
.
delete_installation_pod!
(
command
.
pod_name
)
end
end
describe
'#helm_init_command'
do
subject
{
helm
.
send
(
:helm_init_command
,
command
)
}
context
'when command.install_helm is true'
do
let
(
:install_helm
)
{
true
}
it
{
is_expected
.
to
eq
(
'helm init >/dev/null'
)
}
end
context
'when command.install_helm is false'
do
let
(
:install_helm
)
{
false
}
it
{
is_expected
.
to
eq
(
'helm init --client-only >/dev/null'
)
}
end
end
describe
'#helm_install_command'
do
subject
{
helm
.
send
(
:helm_install_command
,
command
)
}
context
'when command.chart is nil'
do
let
(
:chart
)
{
nil
}
it
{
is_expected
.
to
be_nil
}
end
context
'when command.chart is set'
do
let
(
:chart
)
{
'stable/a_chart'
}
it
{
is_expected
.
to
eq
(
"helm install
#{
chart
}
--name
#{
application_name
}
--namespace
#{
namespace
.
name
}
>/dev/null"
)}
end
end
end
spec/models/clusters/applications/helm_spec.rb
View file @
1f43d563
...
...
@@ -38,6 +38,12 @@ describe Clusters::Applications::Helm do
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:
true
,
chart:
nil
)
end
end
describe
'status state machine'
do
describe
'#make_installing'
do
subject
{
create
(
:cluster_applications_helm
,
:scheduled
)
}
...
...
spec/services/clusters/applications/install_service_spec.rb
View file @
1f43d563
...
...
@@ -12,7 +12,7 @@ describe Clusters::Applications::InstallService do
context
'when there are no errors'
do
before
do
expect
(
helm_client
).
to
receive
(
:install
).
with
(
application
)
expect
(
helm_client
).
to
receive
(
:install
).
with
(
application
.
install_command
)
allow
(
ClusterWaitForAppInstallationWorker
).
to
receive
(
:perform_in
).
and_return
(
nil
)
end
...
...
@@ -33,7 +33,7 @@ describe Clusters::Applications::InstallService do
context
'when k8s cluster communication fails'
do
before
do
error
=
KubeException
.
new
(
500
,
'system failure'
,
nil
)
expect
(
helm_client
).
to
receive
(
:install
).
with
(
application
).
and_raise
(
error
)
expect
(
helm_client
).
to
receive
(
:install
).
with
(
application
.
install_command
).
and_raise
(
error
)
end
it
'make the application errored'
do
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment