Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
H
helm3
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
helm3
Commits
d97086cb
Commit
d97086cb
authored
Apr 11, 2017
by
Matt Butcher
Committed by
GitHub
Apr 11, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2229 from technosophos/feat/chart-tiller-version
feat(tiller): support version constraint on chart
parents
382e2b42
e4e0e320
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
147 additions
and
33 deletions
+147
-33
metadata.proto
_proto/hapi/chart/metadata.proto
+5
-1
conventions.md
docs/chart_best_practices/conventions.md
+19
-2
charts.md
docs/charts.md
+1
-0
metadata.pb.go
pkg/proto/hapi/chart/metadata.pb.go
+27
-23
release_server.go
pkg/tiller/release_server.go
+7
-0
release_server_test.go
pkg/tiller/release_server_test.go
+54
-7
compatible.go
pkg/version/compatible.go
+11
-0
compatible_test.go
pkg/version/compatible_test.go
+23
-0
No files found.
_proto/hapi/chart/metadata.proto
View file @
d97086cb
...
...
@@ -73,7 +73,11 @@ message Metadata {
// The version of the application enclosed inside of this chart.
string
appVersion
=
13
;
// Whether or not this chart is deprecated
bool
deprecated
=
14
;
// TillerVersion is a SemVer constraints on what version of Tiller is required.
// See SemVer ranges here: https://github.com/Masterminds/semver#basic-comparisons
string
tillerVersion
=
15
;
}
docs/chart_best_practices/conventions.md
View file @
d97086cb
...
...
@@ -38,4 +38,22 @@ There are a few small conventions followed for using the words Helm, helm, Tille
-
`tiller`
is the name of the binary run on the backend
-
The term 'chart' does not need to be capitalized, as it is not a proper noun.
When in doubt, use _Helm_ (with an uppercase 'H').
\ No newline at end of file
When in doubt, use _Helm_ (with an uppercase 'H').
## Restricting Tiller by Version
A
`Chart.yaml`
file can specify a
`tillerVersion`
SemVer constraint:
```
yaml
name
:
mychart
version
:
0.2.0
tillerVersion
:
"
>=2.4.0"
```
This constraint should be set when templates use a new feature that was not
supported in older versions of Helm. While this parameter will accept sophisticated
SemVer rules, the best practice is to default to the form
`>=2.4.0`
, where
`2.4.0`
is the version that introduced the new feature used in the chart.
This feature was introduced in Helm 2.4.0, so any version of Tiller older than
2.
4.0 will simply ignore this field.
docs/charts.md
View file @
d97086cb
...
...
@@ -55,6 +55,7 @@ engine: gotpl # The name of the template engine (optional, defaults to gotpl)
icon
:
A URL to an SVG or PNG image to be used as an icon (optional).
appVersion
:
The version of the app that this contains (optional). This needn't be SemVer.
deprecated
:
Whether or not this chart is deprecated (optional, boolean)
tillerVersion
:
The version of Tiller that this chart requires. This should be expressed as a SemVer range
:
"
>2.0.0"
(optional)
```
If you are familiar with the
`Chart.yaml`
file format for Helm Classic, you will
...
...
pkg/proto/hapi/chart/metadata.pb.go
View file @
d97086cb
...
...
@@ -79,6 +79,9 @@ type Metadata struct {
AppVersion
string
`protobuf:"bytes,13,opt,name=appVersion" json:"appVersion,omitempty"`
// Whether or not this chart is deprecated
Deprecated
bool
`protobuf:"varint,14,opt,name=deprecated" json:"deprecated,omitempty"`
// TillerVersion is a SemVer constraints on what version of Tiller is required.
// See SemVer ranges here: https://github.com/Masterminds/semver#basic-comparisons
TillerVersion
string
`protobuf:"bytes,15,opt,name=tillerVersion" json:"tillerVersion,omitempty"`
}
func
(
m
*
Metadata
)
Reset
()
{
*
m
=
Metadata
{}
}
...
...
@@ -102,27 +105,28 @@ func init() {
func
init
()
{
proto
.
RegisterFile
(
"hapi/chart/metadata.proto"
,
fileDescriptor2
)
}
var
fileDescriptor2
=
[]
byte
{
// 339 bytes of a gzipped FileDescriptorProto
0x1f
,
0x8b
,
0x08
,
0x00
,
0x00
,
0x09
,
0x6e
,
0x88
,
0x02
,
0xff
,
0x6c
,
0x92
,
0x4f
,
0x4b
,
0xeb
,
0x40
,
0x14
,
0xc5
,
0x5f
,
0x5e
,
0x9a
,
0x7f
,
0x37
,
0xef
,
0x3d
,
0xca
,
0xf0
,
0x28
,
0xa3
,
0x88
,
0x84
,
0xae
,
0xb2
,
0x4a
,
0x41
,
0x41
,
0x5c
,
0x0b
,
0xe2
,
0x42
,
0xdb
,
0x4a
,
0xf0
,
0x0f
,
0xb8
,
0x1b
,
0x93
,
0x4b
,
0x3b
,
0x68
,
0x66
,
0xc2
,
0xcc
,
0xa8
,
0xf8
,
0xe5
,
0xfc
,
0x6c
,
0x32
,
0x93
,
0xa4
,
0xcd
,
0xc2
,
0xdd
,
0x3d
,
0xe7
,
0x97
,
0x7b
,
0x92
,
0x73
,
0x09
,
0x1c
,
0x6c
,
0x59
,
0xcb
,
0x17
,
0xd5
,
0x96
,
0x29
,
0xb3
,
0x68
,
0xd0
,
0xb0
,
0x9a
,
0x19
,
0x56
,
0xb4
,
0x4a
,
0x1a
,
0x49
,
0xc0
,
0xa2
,
0xc2
,
0xa1
,
0xf9
,
0x19
,
0xc0
,
0x92
,
0x71
,
0x61
,
0x18
,
0x17
,
0xa8
,
0x08
,
0x81
,
0x89
,
0x60
,
0x0d
,
0x52
,
0x2f
,
0xf3
,
0xf2
,
0xa4
,
0x74
,
0x33
,
0xf9
,
0x0f
,
0x01
,
0x36
,
0x8c
,
0xbf
,
0xd2
,
0xdf
,
0xce
,
0xec
,
0xc4
,
0xfc
,
0xcb
,
0x87
,
0x78
,
0xd9
,
0xc7
,
0xfe
,
0xb8
,
0x46
,
0x60
,
0xb2
,
0x95
,
0x0d
,
0xf6
,
0x5b
,
0x6e
,
0x26
,
0x14
,
0x22
,
0x2d
,
0xdf
,
0x54
,
0x85
,
0x9a
,
0xfa
,
0x99
,
0x9f
,
0x27
,
0xe5
,
0x20
,
0x2d
,
0x79
,
0x47
,
0xa5
,
0xb9
,
0x14
,
0x74
,
0xe2
,
0x16
,
0x06
,
0x49
,
0x32
,
0x48
,
0x6b
,
0xd4
,
0x95
,
0xe2
,
0xad
,
0xb1
,
0x34
,
0x70
,
0x74
,
0x6c
,
0x91
,
0x43
,
0x88
,
0x5f
,
0xf0
,
0xf3
,
0x43
,
0xaa
,
0x5a
,
0xd3
,
0xd0
,
0xc5
,
0xee
,
0x34
,
0x39
,
0x87
,
0xb4
,
0xd9
,
0xd5
,
0xd3
,
0x34
,
0xca
,
0xfc
,
0x3c
,
0x3d
,
0x99
,
0x15
,
0xfb
,
0x03
,
0x14
,
0xfb
,
0xf6
,
0xe5
,
0xf8
,
0x51
,
0x32
,
0x83
,
0x10
,
0xc5
,
0x86
,
0x0b
,
0xa4
,
0xb1
,
0x7b
,
0x65
,
0xaf
,
0x6c
,
0x2f
,
0x5e
,
0x49
,
0x41
,
0x93
,
0xae
,
0x97
,
0x9d
,
0xc9
,
0x31
,
0x00
,
0x6b
,
0xf9
,
0x43
,
0x5f
,
0x00
,
0x1c
,
0x19
,
0x39
,
0xe4
,
0x08
,
0x92
,
0x4a
,
0x8a
,
0x9a
,
0xbb
,
0x06
,
0xa9
,
0xc3
,
0x7b
,
0xc3
,
0x26
,
0x1a
,
0xb6
,
0xd1
,
0xf4
,
0x4f
,
0x97
,
0x68
,
0xe7
,
0x2e
,
0xb1
,
0x1d
,
0x12
,
0xff
,
0x0e
,
0x89
,
0x83
,
0x63
,
0x79
,
0x8d
,
0xad
,
0xc2
,
0x8a
,
0x19
,
0xac
,
0xe9
,
0xbf
,
0xcc
,
0xcb
,
0xe3
,
0x72
,
0xe4
,
0xcc
,
0x33
,
0x08
,
0x2f
,
0xbb
,
0xef
,
0x4d
,
0x21
,
0xba
,
0x5f
,
0x5d
,
0xaf
,
0xd6
,
0x8f
,
0xab
,
0xe9
,
0x2f
,
0x92
,
0x40
,
0x70
,
0xb5
,
0xbe
,
0xbb
,
0xbd
,
0x99
,
0x7a
,
0x17
,
0xd1
,
0x53
,
0xe0
,
0x0e
,
0xf0
,
0x1c
,
0xba
,
0x9f
,
0xe2
,
0xf4
,
0x3b
,
0x00
,
0x00
,
0xff
,
0xff
,
0x08
,
0xf3
,
0xcc
,
0x66
,
0x31
,
0x02
,
0x00
,
0x00
,
// 354 bytes of a gzipped FileDescriptorProto
0x1f
,
0x8b
,
0x08
,
0x00
,
0x00
,
0x09
,
0x6e
,
0x88
,
0x02
,
0xff
,
0x6c
,
0x92
,
0x5f
,
0x4b
,
0xe3
,
0x40
,
0x14
,
0xc5
,
0x37
,
0x9b
,
0xe6
,
0xdf
,
0xcd
,
0x76
,
0xb7
,
0x0c
,
0x4b
,
0x99
,
0x5d
,
0x44
,
0x42
,
0xf1
,
0x21
,
0x4f
,
0x29
,
0x28
,
0x88
,
0xcf
,
0x82
,
0xf8
,
0xa0
,
0x6d
,
0x25
,
0xf8
,
0x07
,
0x7c
,
0x1b
,
0x93
,
0x4b
,
0x3b
,
0xd8
,
0xcc
,
0x84
,
0xc9
,
0xa8
,
0xf8
,
0x7d
,
0xfd
,
0x20
,
0x32
,
0x93
,
0xa4
,
0x8d
,
0xe0
,
0xdb
,
0x3d
,
0xe7
,
0xe4
,
0xfe
,
0xc2
,
0xb9
,
0x0c
,
0xfc
,
0xdb
,
0xb0
,
0x9a
,
0xcf
,
0x8b
,
0x0d
,
0x53
,
0x7a
,
0x5e
,
0xa1
,
0x66
,
0x25
,
0xd3
,
0x2c
,
0xab
,
0x95
,
0xd4
,
0x92
,
0x80
,
0x89
,
0x32
,
0x1b
,
0xcd
,
0x4e
,
0x01
,
0x16
,
0x8c
,
0x0b
,
0xcd
,
0xb8
,
0x40
,
0x45
,
0x08
,
0x8c
,
0x04
,
0xab
,
0x90
,
0x3a
,
0x89
,
0x93
,
0x46
,
0xb9
,
0x9d
,
0xc9
,
0x5f
,
0xf0
,
0xb0
,
0x62
,
0x7c
,
0x4b
,
0x7f
,
0x5a
,
0xb3
,
0x15
,
0xb3
,
0x0f
,
0x17
,
0xc2
,
0x45
,
0x87
,
0xfd
,
0x76
,
0x8d
,
0xc0
,
0x68
,
0x23
,
0x2b
,
0xec
,
0xb6
,
0xec
,
0x4c
,
0x28
,
0x04
,
0x8d
,
0x7c
,
0x51
,
0x05
,
0x36
,
0xd4
,
0x4d
,
0xdc
,
0x34
,
0xca
,
0x7b
,
0x69
,
0x92
,
0x57
,
0x54
,
0x0d
,
0x97
,
0x82
,
0x8e
,
0xec
,
0x42
,
0x2f
,
0x49
,
0x02
,
0x71
,
0x89
,
0x4d
,
0xa1
,
0x78
,
0xad
,
0x4d
,
0xea
,
0xd9
,
0x74
,
0x68
,
0x91
,
0xff
,
0x10
,
0x3e
,
0xe3
,
0xfb
,
0x9b
,
0x54
,
0x65
,
0x43
,
0x7d
,
0x8b
,
0xdd
,
0x69
,
0x72
,
0x06
,
0x71
,
0xb5
,
0xab
,
0xd7
,
0xd0
,
0x20
,
0x71
,
0xd3
,
0xf8
,
0x78
,
0x9a
,
0xed
,
0x0f
,
0x90
,
0xed
,
0xdb
,
0xe7
,
0xc3
,
0x4f
,
0xc9
,
0x14
,
0x7c
,
0x14
,
0x6b
,
0x2e
,
0x90
,
0x86
,
0xf6
,
0x97
,
0x9d
,
0x32
,
0xbd
,
0x78
,
0x21
,
0x05
,
0x8d
,
0xda
,
0x5e
,
0x66
,
0x26
,
0x87
,
0x00
,
0xac
,
0xe6
,
0xf7
,
0x5d
,
0x01
,
0xb0
,
0xc9
,
0xc0
,
0x21
,
0x07
,
0x10
,
0x15
,
0x52
,
0x94
,
0xdc
,
0x36
,
0x88
,
0x6d
,
0xbc
,
0x37
,
0x0c
,
0x51
,
0xb3
,
0x75
,
0x43
,
0x7f
,
0xb5
,
0x44
,
0x33
,
0xb7
,
0xc4
,
0xba
,
0x27
,
0x8e
,
0x7b
,
0x62
,
0xef
,
0x98
,
0xbc
,
0xc4
,
0x5a
,
0x61
,
0xc1
,
0x34
,
0x96
,
0xf4
,
0x77
,
0xe2
,
0xa4
,
0x61
,
0x3e
,
0x70
,
0xc8
,
0x11
,
0x8c
,
0x35
,
0xdf
,
0x6e
,
0x51
,
0xf5
,
0x88
,
0x3f
,
0x16
,
0xf1
,
0xd5
,
0x9c
,
0x25
,
0xe0
,
0x5f
,
0xb4
,
0xad
,
0x62
,
0x08
,
0xee
,
0x96
,
0x57
,
0xcb
,
0xd5
,
0xc3
,
0x72
,
0xf2
,
0x83
,
0x44
,
0xe0
,
0x5d
,
0xae
,
0x6e
,
0x6f
,
0xae
,
0x27
,
0xce
,
0x79
,
0xf0
,
0xe8
,
0xd9
,
0x33
,
0x3d
,
0xf9
,
0xf6
,
0xe9
,
0x9c
,
0x7c
,
0x06
,
0x00
,
0x00
,
0xff
,
0xff
,
0xea
,
0xb5
,
0x4c
,
0xbe
,
0x57
,
0x02
,
0x00
,
0x00
,
}
pkg/tiller/release_server.go
View file @
d97086cb
...
...
@@ -776,6 +776,13 @@ func getVersionSet(client discovery.ServerGroupsInterface) (chartutil.VersionSet
}
func
(
s
*
ReleaseServer
)
renderResources
(
ch
*
chart
.
Chart
,
values
chartutil
.
Values
,
vs
chartutil
.
VersionSet
)
([]
*
release
.
Hook
,
*
bytes
.
Buffer
,
string
,
error
)
{
// Guard to make sure Tiller is at the right version to handle this chart.
sver
:=
version
.
GetVersion
()
if
ch
.
Metadata
.
TillerVersion
!=
""
&&
!
version
.
IsCompatibleRange
(
ch
.
Metadata
.
TillerVersion
,
sver
)
{
return
nil
,
nil
,
""
,
fmt
.
Errorf
(
"Chart incompatible with Tiller %s"
,
sver
)
}
renderer
:=
s
.
engine
(
ch
)
files
,
err
:=
renderer
.
Render
(
ch
,
values
)
if
err
!=
nil
{
...
...
pkg/tiller/release_server_test.go
View file @
d97086cb
...
...
@@ -325,7 +325,7 @@ func TestInstallRelease(t *testing.T) {
}
}
func
TestInstallReleaseWithNotes
(
t
*
testing
.
T
)
{
func
TestInstallRelease
_
WithNotes
(
t
*
testing
.
T
)
{
c
:=
helm
.
NewContext
()
rs
:=
rsFixture
()
...
...
@@ -394,7 +394,7 @@ func TestInstallReleaseWithNotes(t *testing.T) {
}
}
func
TestInstallReleaseWithNotesRendered
(
t
*
testing
.
T
)
{
func
TestInstallRelease
_
WithNotesRendered
(
t
*
testing
.
T
)
{
c
:=
helm
.
NewContext
()
rs
:=
rsFixture
()
...
...
@@ -464,7 +464,54 @@ func TestInstallReleaseWithNotesRendered(t *testing.T) {
}
}
func
TestInstallReleaseWithChartAndDependencyNotes
(
t
*
testing
.
T
)
{
func
TestInstallRelease_TillerVersion
(
t
*
testing
.
T
)
{
c
:=
helm
.
NewContext
()
rs
:=
rsFixture
()
// TODO: Refactor this into a mock.
req
:=
&
services
.
InstallReleaseRequest
{
Namespace
:
"spaced"
,
Chart
:
&
chart
.
Chart
{
Metadata
:
&
chart
.
Metadata
{
Name
:
"hello"
,
TillerVersion
:
">=2.2.0"
},
Templates
:
[]
*
chart
.
Template
{
{
Name
:
"templates/hello"
,
Data
:
[]
byte
(
"hello: world"
)},
{
Name
:
"templates/hooks"
,
Data
:
[]
byte
(
manifestWithHook
)},
},
},
}
_
,
err
:=
rs
.
InstallRelease
(
c
,
req
)
if
err
!=
nil
{
t
.
Fatalf
(
"Expected valid range. Got %q"
,
err
)
}
}
func
TestInstallRelease_WrongTillerVersion
(
t
*
testing
.
T
)
{
c
:=
helm
.
NewContext
()
rs
:=
rsFixture
()
// TODO: Refactor this into a mock.
req
:=
&
services
.
InstallReleaseRequest
{
Namespace
:
"spaced"
,
Chart
:
&
chart
.
Chart
{
Metadata
:
&
chart
.
Metadata
{
Name
:
"hello"
,
TillerVersion
:
"<2.0.0"
},
Templates
:
[]
*
chart
.
Template
{
{
Name
:
"templates/hello"
,
Data
:
[]
byte
(
"hello: world"
)},
{
Name
:
"templates/hooks"
,
Data
:
[]
byte
(
manifestWithHook
)},
},
},
}
_
,
err
:=
rs
.
InstallRelease
(
c
,
req
)
if
err
==
nil
{
t
.
Fatalf
(
"Expected to fail because of wrong version"
)
}
expect
:=
"Chart incompatible with Tiller"
if
!
strings
.
Contains
(
err
.
Error
(),
expect
)
{
t
.
Errorf
(
"Expected %q to contain %q"
,
err
.
Error
(),
expect
)
}
}
func
TestInstallRelease_WithChartAndDependencyNotes
(
t
*
testing
.
T
)
{
c
:=
helm
.
NewContext
()
rs
:=
rsFixture
()
...
...
@@ -515,7 +562,7 @@ func TestInstallReleaseWithChartAndDependencyNotes(t *testing.T) {
}
}
func
TestInstallReleaseDryRun
(
t
*
testing
.
T
)
{
func
TestInstallRelease
_
DryRun
(
t
*
testing
.
T
)
{
c
:=
helm
.
NewContext
()
rs
:=
rsFixture
()
...
...
@@ -568,7 +615,7 @@ func TestInstallReleaseDryRun(t *testing.T) {
}
}
func
TestInstallReleaseNoHooks
(
t
*
testing
.
T
)
{
func
TestInstallRelease
_
NoHooks
(
t
*
testing
.
T
)
{
c
:=
helm
.
NewContext
()
rs
:=
rsFixture
()
rs
.
env
.
Releases
.
Create
(
releaseStub
())
...
...
@@ -587,7 +634,7 @@ func TestInstallReleaseNoHooks(t *testing.T) {
}
}
func
TestInstallReleaseFailedHooks
(
t
*
testing
.
T
)
{
func
TestInstallRelease
_
FailedHooks
(
t
*
testing
.
T
)
{
c
:=
helm
.
NewContext
()
rs
:=
rsFixture
()
rs
.
env
.
Releases
.
Create
(
releaseStub
())
...
...
@@ -606,7 +653,7 @@ func TestInstallReleaseFailedHooks(t *testing.T) {
}
}
func
TestInstallReleaseReuseName
(
t
*
testing
.
T
)
{
func
TestInstallRelease
_
ReuseName
(
t
*
testing
.
T
)
{
c
:=
helm
.
NewContext
()
rs
:=
rsFixture
()
rel
:=
releaseStub
()
...
...
pkg/version/compatible.go
View file @
d97086cb
...
...
@@ -38,6 +38,17 @@ func IsCompatible(client, server string) bool {
constraint
=
cv
.
String
()
}
return
IsCompatibleRange
(
constraint
,
server
)
}
// IsCompatibleRange compares a version to a constraint.
// It returns true if the version matches the constraint, and false in all other cases.
func
IsCompatibleRange
(
constraint
,
ver
string
)
bool
{
sv
,
err
:=
semver
.
NewVersion
(
ver
)
if
err
!=
nil
{
return
false
}
c
,
err
:=
semver
.
NewConstraint
(
constraint
)
if
err
!=
nil
{
return
false
...
...
pkg/version/compatible_test.go
View file @
d97086cb
...
...
@@ -41,3 +41,26 @@ func TestIsCompatible(t *testing.T) {
}
}
}
func
TestIsCompatibleRange
(
t
*
testing
.
T
)
{
tests
:=
[]
struct
{
constraint
string
ver
string
expected
bool
}{
{
"v2.0.0-alpha.4"
,
"v2.0.0-alpha.4"
,
true
},
{
"v2.0.0-alpha.3"
,
"v2.0.0-alpha.4"
,
false
},
{
"v2.0.0"
,
"v2.0.0-alpha.4"
,
false
},
{
"v2.0.0-alpha.4"
,
"v2.0.0"
,
false
},
{
"~v2.0.0"
,
"v2.0.1"
,
true
},
{
"v2"
,
"v2.0.0"
,
true
},
{
">2.0.0"
,
"v2.1.1"
,
true
},
{
"v2.1.*"
,
"v2.1.1"
,
true
},
}
for
_
,
tt
:=
range
tests
{
if
IsCompatibleRange
(
tt
.
constraint
,
tt
.
ver
)
!=
tt
.
expected
{
t
.
Errorf
(
"expected constraint %s to be %v for %s"
,
tt
.
constraint
,
tt
.
expected
,
tt
.
ver
)
}
}
}
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