Merge branch 'master' into togglable-tiller-probe-endpoints

pull/5561/head
KUOKA Yusuke 6 years ago committed by GitHub
commit 3d8f8b866c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -4,7 +4,7 @@ jobs:
working_directory: /go/src/k8s.io/helm
parallelism: 3
docker:
- image: golang:1.12.1
- image: golang:1.12.5
environment:
PROJECT_NAME: "kubernetes-helm"
steps:

@ -172,10 +172,44 @@ contributing to Helm. All issue types follow the same general lifecycle. Differe
## How to Contribute a Patch
1. Fork the repo, develop and test your code changes.
1. Use sign-off when making each of your commits (see [above](#sign-your-work)).
1. **Fork** the repo [helm](https://github.com/helm/helm)
Go to https://github.com/helm/helm then hit the `Fork` button to fork your own copy of repository **helm** to your github account.
2. **Clone** the forked repo to your local working directory.
```sh
$ git clone https://github.com/$your_github_account/helm.git
```
3. Add an `upstream` remote to keep your fork in sync with the main repo.
```sh
$ cd helm
$ git remote add upstream https://github.com/helm/helm.git
$ git remote -v
origin https://github.com/$your_github_account/helm.git (fetch)
origin https://github.com/$your_github_account/helm.git (push)
upstream https://github.com/helm/helm.git (fetch)
upstream https://github.com/helm/helm.git (push)
```
4. Sync your local `master` branch.
```sh
$ git pull upstream master
```
5. Create a branch to add a new feature or fix issues.
```sh
$ git checkout -b new-feature
```
6. Make any change on the branch `new-feature` then build and test your codes.
7. Include in what will be committed.
```sh
$ git add <file>
```
8. Use sign-off when making each of your commits (see [above](#sign-your-work)).
If you forgot to sign some commits that are part of the contribution, you can ask [git to rewrite your commit history](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History).
1. Submit a pull request.
```sh
$ git commit --signoff
```
9. Submit a pull request.
Coding conventions and standards are explained in the official developer docs:
[Developers Guide](docs/developers.md)

@ -1,6 +1,6 @@
DOCKER_REGISTRY ?= gcr.io
IMAGE_PREFIX ?= kubernetes-helm
DEV_IMAGE ?= golang:1.12.1
DEV_IMAGE ?= golang:1.12.5
SHORT_NAME ?= tiller
SHORT_NAME_RUDDER ?= rudder
TARGETS ?= darwin/amd64 linux/amd64 linux/386 linux/arm linux/arm64 linux/ppc64le linux/s390x windows/amd64

@ -1,24 +1,11 @@
maintainers:
- adamreese
- bacongobbler
- jascott1
- mattfarina
- michelleN
- nebril
- prydonius
- SlickNik
- technosophos
- thomastaylor312
- viglesiasce
reviewers:
- adamreese
- bacongobbler
- fibonacci1729
- hickeyma
- jascott1
- mattfarina
- michelleN
- migmartri
- nebril
- prydonius
- SlickNik
- technosophos
@ -26,6 +13,7 @@ reviewers:
- viglesiasce
emeritus:
- migmartri
- nebril
- seh
- vaikas-google
- rimusz

@ -7,4 +7,4 @@ Packages
- `hapi.release` Information about installed charts (Releases) such as metadata about when they were installed, their status, and how they were configured.
- `hapi.services.rudder` Definition for the ReleaseModuleService used by Tiller to manipulate releases on a given node
- `hapi.services.tiller` Definition of the ReleaseService provided by Tiller and used by Helm clients to manipulate releases cluster wide.
- `hapi.version` Version meta-data used by tiller to express it's version
- `hapi.version` Version metadata used by Tiller to express its version

@ -45,6 +45,7 @@ type getCmd struct {
out io.Writer
client helm.Interface
version int32
template string
}
func newGetCmd(client helm.Interface, out io.Writer) *cobra.Command {
@ -73,6 +74,7 @@ func newGetCmd(client helm.Interface, out io.Writer) *cobra.Command {
f := cmd.Flags()
settings.AddFlagsTLS(f)
f.Int32Var(&get.version, "revision", 0, "get the named release with revision")
f.StringVar(&get.template, "template", "", "go template for formatting the output, eg: {{.Release.Name}}")
cmd.AddCommand(newGetValuesCmd(nil, out))
cmd.AddCommand(newGetManifestCmd(nil, out))
@ -91,5 +93,9 @@ func (g *getCmd) run() error {
if err != nil {
return prettyError(err)
}
if g.template != "" {
return tpl(g.template, res, g.out)
}
return printRelease(g.out, res.Release)
}

@ -35,6 +35,13 @@ func TestGetCmd(t *testing.T) {
expected: "REVISION: 1\nRELEASED: (.*)\nCHART: foo-0.1.0-beta.1\nUSER-SUPPLIED VALUES:\nname: \"value\"\nCOMPUTED VALUES:\nname: value\n\nHOOKS:\n---\n# pre-install-hook\n" + helm.MockHookTemplate + "\nMANIFEST:",
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide"})},
},
{
name: "get with a formatted release",
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "elevated-turkey"}),
args: []string{"elevated-turkey", "--template", "{{.Release.Chart.Metadata.Version}}"},
expected: "0.1.0-beta.1",
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "elevated-turkey"})},
},
{
name: "get requires release name arg",
err: true,

@ -61,19 +61,19 @@ Common actions from this point include:
- helm list: list releases of charts
Environment:
$HELM_HOME set an alternative location for Helm files. By default, these are stored in ~/.helm
$HELM_HOST set an alternative Tiller host. The format is host:port
$HELM_NO_PLUGINS disable plugins. Set HELM_NO_PLUGINS=1 to disable plugins.
$TILLER_NAMESPACE set an alternative Tiller namespace (default "kube-system")
$KUBECONFIG set an alternative Kubernetes configuration file (default "~/.kube/config")
$HELM_TLS_CA_CERT path to TLS CA certificate used to verify the Helm client and Tiller server certificates (default "$HELM_HOME/ca.pem")
$HELM_TLS_CERT path to TLS client certificate file for authenticating to Tiller (default "$HELM_HOME/cert.pem")
$HELM_TLS_KEY path to TLS client key file for authenticating to Tiller (default "$HELM_HOME/key.pem")
$HELM_TLS_ENABLE enable TLS connection between Helm and Tiller (default "false")
$HELM_TLS_VERIFY enable TLS connection between Helm and Tiller and verify Tiller server certificate (default "false")
$HELM_TLS_HOSTNAME the hostname or IP address used to verify the Tiller server certificate (default "127.0.0.1")
$HELM_KEY_PASSPHRASE set HELM_KEY_PASSPHRASE to the passphrase of your PGP private key. If set, you will not be prompted for
the passphrase while signing helm charts
- $HELM_HOME: set an alternative location for Helm files. By default, these are stored in ~/.helm
- $HELM_HOST: set an alternative Tiller host. The format is host:port
- $HELM_NO_PLUGINS: disable plugins. Set HELM_NO_PLUGINS=1 to disable plugins.
- $TILLER_NAMESPACE: set an alternative Tiller namespace (default "kube-system")
- $KUBECONFIG: set an alternative Kubernetes configuration file (default "~/.kube/config")
- $HELM_TLS_CA_CERT: path to TLS CA certificate used to verify the Helm client and Tiller server certificates (default "$HELM_HOME/ca.pem")
- $HELM_TLS_CERT: path to TLS client certificate file for authenticating to Tiller (default "$HELM_HOME/cert.pem")
- $HELM_TLS_KEY: path to TLS client key file for authenticating to Tiller (default "$HELM_HOME/key.pem")
- $HELM_TLS_ENABLE: enable TLS connection between Helm and Tiller (default "false")
- $HELM_TLS_VERIFY: enable TLS connection between Helm and Tiller and verify Tiller server certificate (default "false")
- $HELM_TLS_HOSTNAME: the hostname or IP address used to verify the Tiller server certificate (default "127.0.0.1")
- $HELM_KEY_PASSPHRASE: set HELM_KEY_PASSPHRASE to the passphrase of your PGP private key. If set, you will not be prompted for the passphrase while signing helm charts
`

@ -310,7 +310,6 @@ func (i *initCmd) run() error {
"$ helm init --tiller-image gcr.io/kubernetes-helm/tiller:v2.8.2\n\n")
}
fmt.Fprintln(i.out, "Happy Helming!")
return nil
}

@ -27,27 +27,26 @@ import (
"k8s.io/helm/pkg/chartutil"
)
const inspectDesc = `
const (
inspectDesc = `
This command inspects a chart and displays information. It takes a chart reference
('stable/drupal'), a full path to a directory or packaged chart, or a URL.
Inspect prints the contents of the Chart.yaml file and the values.yaml file.
`
const inspectValuesDesc = `
inspectValuesDesc = `
This command inspects a chart (directory, file, or URL) and displays the contents
of the values.yaml file
`
const inspectChartDesc = `
inspectChartDesc = `
This command inspects a chart (directory, file, or URL) and displays the contents
of the Charts.yaml file
`
const readmeChartDesc = `
readmeChartDesc = `
This command inspects a chart (directory, file, or URL) and displays the contents
of the README file
`
)
type inspectCmd struct {
chartpath string

@ -36,6 +36,7 @@ import (
"k8s.io/helm/pkg/version"
"k8s.io/helm/pkg/chartutil"
"k8s.io/helm/pkg/tiller/environment"
)
// Install uses Kubernetes client to install Tiller.
@ -226,8 +227,8 @@ func generateDeployment(opts *Options) (*v1beta1.Deployment, error) {
Image: opts.SelectImage(),
ImagePullPolicy: opts.pullPolicy(),
Ports: []v1.ContainerPort{
{ContainerPort: 44134, Name: "tiller"},
{ContainerPort: 44135, Name: "http"},
{ContainerPort: environment.DefaultTillerPort, Name: "tiller"},
{ContainerPort: environment.DefaultTillerProbePort, Name: "http"},
},
Env: []v1.EnvVar{
{Name: "TILLER_NAMESPACE", Value: opts.Namespace},
@ -237,7 +238,7 @@ func generateDeployment(opts *Options) (*v1beta1.Deployment, error) {
Handler: v1.Handler{
HTTPGet: &v1.HTTPGetAction{
Path: "/liveness",
Port: intstr.FromInt(44135),
Port: intstr.FromInt(environment.DefaultTillerProbePort),
},
},
InitialDelaySeconds: 1,
@ -247,7 +248,7 @@ func generateDeployment(opts *Options) (*v1beta1.Deployment, error) {
Handler: v1.Handler{
HTTPGet: &v1.HTTPGetAction{
Path: "/readiness",
Port: intstr.FromInt(44135),
Port: intstr.FromInt(environment.DefaultTillerProbePort),
},
},
InitialDelaySeconds: 1,
@ -341,7 +342,7 @@ func generateService(namespace string) *v1.Service {
Ports: []v1.ServicePort{
{
Name: "tiller",
Port: 44134,
Port: environment.DefaultTillerPort,
TargetPort: intstr.FromString("tiller"),
},
},

@ -24,7 +24,12 @@ import (
"k8s.io/helm/pkg/version"
)
const defaultImage = "gcr.io/kubernetes-helm/tiller"
const (
defaultImage = "gcr.io/kubernetes-helm/tiller"
fmtJSON OutputFormat = "json"
fmtYAML OutputFormat = "yaml"
)
// Options control how to install Tiller into a cluster, upgrade, and uninstall Tiller from a cluster.
type Options struct {
@ -154,11 +159,6 @@ func (f *OutputFormat) Type() string {
return "OutputFormat"
}
const (
fmtJSON OutputFormat = "json"
fmtYAML OutputFormat = "yaml"
)
// Set validates and sets the value of the OutputFormat
func (f *OutputFormat) Set(s string) error {
for _, of := range []OutputFormat{fmtJSON, fmtYAML} {

@ -166,7 +166,7 @@ func lintChart(path string, vals []byte, namespace string, strict bool) (support
chartPath = path
}
// Guard: Error out of this is not a chart.
// Guard: Error out if this is not a chart.
if _, err := os.Stat(filepath.Join(chartPath, "Chart.yaml")); err != nil {
return linter, errLintNoChart
}
@ -177,7 +177,7 @@ func lintChart(path string, vals []byte, namespace string, strict bool) (support
// vals merges values from files specified via -f/--values and
// directly via --set or --set-string or --set-file, marshaling them to YAML
//
// This func is implemented intentionally and separately from the `vals` func for the `install` and `upgrade` comammdsn.
// This func is implemented intentionally and separately from the `vals` func for the `install` and `upgrade` commands.
// Compared to the alternative func, this func lacks the parameters for tls opts - ca key, cert, and ca cert.
// That's because this command, `lint`, is explicitly forbidden from making server connections.
func (l *lintCmd) vals() ([]byte, error) {

@ -66,7 +66,7 @@ func printRelease(out io.Writer, rel *release.Release) error {
return tpl(printReleaseTemplate, data, out)
}
func tpl(t string, vals map[string]interface{}, out io.Writer) error {
func tpl(t string, vals interface{}, out io.Writer) error {
tt, err := template.New("_").Parse(t)
if err != nil {
return err

@ -125,6 +125,6 @@ func updateCharts(repos []*repo.ChartRepository, out io.Writer, home helmpath.Ho
return errors.New("Update Failed. Check log for details")
}
fmt.Fprintln(out, "Update Complete. ⎈ Happy Helming! ⎈")
fmt.Fprintln(out, "Update Complete.")
return nil
}

@ -21,6 +21,7 @@ import (
"fmt"
"io"
"os"
"strings"
"github.com/spf13/cobra"
@ -59,7 +60,11 @@ func newResetCmd(client helm.Interface, out io.Writer) *cobra.Command {
Short: "uninstalls Tiller from a cluster",
Long: resetDesc,
PreRunE: func(cmd *cobra.Command, args []string) error {
if err := setupConnection(); !d.force && err != nil {
err := setupConnection()
if !d.force && err != nil {
return err
}
if d.force && err != nil && strings.EqualFold(err.Error(), "could not find tiller") {
return err
}
return nil

@ -112,7 +112,7 @@ func (r *rollbackCmd) run() error {
return prettyError(err)
}
fmt.Fprintf(r.out, "Rollback was a success! Happy Helming!\n")
fmt.Fprintf(r.out, "Rollback was a success.\n")
return nil
}

@ -31,25 +31,25 @@ func TestRollbackCmd(t *testing.T) {
{
name: "rollback a release",
args: []string{"funny-honey", "1"},
expected: "Rollback was a success! Happy Helming!",
expected: "Rollback was a success.",
},
{
name: "rollback a release with timeout",
args: []string{"funny-honey", "1"},
flags: []string{"--timeout", "120"},
expected: "Rollback was a success! Happy Helming!",
expected: "Rollback was a success.",
},
{
name: "rollback a release with wait",
args: []string{"funny-honey", "1"},
flags: []string{"--wait"},
expected: "Rollback was a success! Happy Helming!",
expected: "Rollback was a success.",
},
{
name: "rollback a release with description",
args: []string{"funny-honey", "1"},
flags: []string{"--description", "foo"},
expected: "Rollback was a success! Happy Helming!",
expected: "Rollback was a success.",
},
{
name: "rollback a release without revision",

@ -33,6 +33,12 @@ import (
"k8s.io/helm/pkg/repo"
)
const (
sep = "\v"
// verSep is a separator for version fields in map keys.
verSep = "$$"
)
// Result is a search result.
//
// Score indicates how close it is to match. The higher the score, the longer
@ -49,16 +55,11 @@ type Index struct {
charts map[string]*repo.ChartVersion
}
const sep = "\v"
// NewIndex creats a new Index.
func NewIndex() *Index {
return &Index{lines: map[string]string{}, charts: map[string]*repo.ChartVersion{}}
}
// verSep is a separator for version fields in map keys.
const verSep = "$$"
// AddRepo adds a repository index to the search index.
func (i *Index) AddRepo(rname string, ind *repo.IndexFile, all bool) {
ind.SortEntries()

@ -1,3 +1,4 @@
appVersion: "3.3"
description: Deploy a basic Alpine Linux pod
home: https://k8s.io/helm
name: alpine

@ -10,6 +10,7 @@ metadata:
# The "release" convention makes it easy to tie a release to all of the
# Kubernetes resources that were created as part of that release.
app.kubernetes.io/instance: {{.Release.Name | quote }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
# This makes it easy to audit chart usage.
helm.sh/chart: "{{.Chart.Name}}-{{.Chart.Version}}"
values: {{.Values.test.Name}}

@ -4,3 +4,4 @@ name: novals
sources:
- https://github.com/helm/helm
version: 0.2.0
appVersion: 3.3

@ -10,6 +10,7 @@ metadata:
# The "release" convention makes it easy to tie a release to all of the
# Kubernetes resources that were created as part of that release.
app.kubernetes.io/instance: {{.Release.Name | quote }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
# This makes it easy to audit chart usage.
helm.sh/chart: "{{.Chart.Name}}-{{.Chart.Version}}"
annotations:

@ -294,6 +294,7 @@ func (u *upgradeCmd) run() error {
description: "",
revision: releaseHistory.Releases[0].Version,
disableHooks: u.disableHooks,
cleanupOnFail: u.cleanupOnFail,
}
if err := rollback.run(); err != nil {
return err
@ -306,7 +307,7 @@ func (u *upgradeCmd) run() error {
printRelease(u.out, resp.Release)
}
fmt.Fprintf(u.out, "Release %q has been upgraded. Happy Helming!\n", u.release)
fmt.Fprintf(u.out, "Release %q has been upgraded.\n", u.release)
// Print the status like status command does
status, err := u.client.ReleaseStatus(u.release)

@ -96,7 +96,7 @@ func TestUpgradeCmd(t *testing.T) {
name: "upgrade a release",
args: []string{"funny-bunny", chartPath},
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 2, Chart: ch}),
expected: "Release \"funny-bunny\" has been upgraded. Happy Helming!\n",
expected: "Release \"funny-bunny\" has been upgraded.\n",
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 2, Chart: ch})},
},
{
@ -104,7 +104,7 @@ func TestUpgradeCmd(t *testing.T) {
args: []string{"funny-bunny", chartPath},
flags: []string{"--timeout", "120"},
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 3, Chart: ch2}),
expected: "Release \"funny-bunny\" has been upgraded. Happy Helming!\n",
expected: "Release \"funny-bunny\" has been upgraded.\n",
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 3, Chart: ch2})},
},
{
@ -112,7 +112,7 @@ func TestUpgradeCmd(t *testing.T) {
args: []string{"funny-bunny", chartPath},
flags: []string{"--reset-values", "true"},
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 4, Chart: ch2}),
expected: "Release \"funny-bunny\" has been upgraded. Happy Helming!\n",
expected: "Release \"funny-bunny\" has been upgraded.\n",
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 4, Chart: ch2})},
},
{
@ -120,7 +120,7 @@ func TestUpgradeCmd(t *testing.T) {
args: []string{"funny-bunny", chartPath},
flags: []string{"--reuse-values", "true"},
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 5, Chart: ch2}),
expected: "Release \"funny-bunny\" has been upgraded. Happy Helming!\n",
expected: "Release \"funny-bunny\" has been upgraded.\n",
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 5, Chart: ch2})},
},
{
@ -128,7 +128,7 @@ func TestUpgradeCmd(t *testing.T) {
args: []string{"funny-bunny", chartPath},
flags: []string{"--atomic"},
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 6, Chart: ch}),
expected: "Release \"funny-bunny\" has been upgraded. Happy Helming!\n",
expected: "Release \"funny-bunny\" has been upgraded.\n",
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 6, Chart: ch})},
},
{
@ -136,7 +136,7 @@ func TestUpgradeCmd(t *testing.T) {
args: []string{"zany-bunny", chartPath},
flags: []string{"-i"},
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "zany-bunny", Version: 1, Chart: ch}),
expected: "Release \"zany-bunny\" has been upgraded. Happy Helming!\n",
expected: "Release \"zany-bunny\" has been upgraded.\n",
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "zany-bunny", Version: 1, Chart: ch})},
},
{
@ -144,7 +144,7 @@ func TestUpgradeCmd(t *testing.T) {
args: []string{"crazy-bunny", chartPath},
flags: []string{"-i", "--timeout", "120"},
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 1, Chart: ch}),
expected: "Release \"crazy-bunny\" has been upgraded. Happy Helming!\n",
expected: "Release \"crazy-bunny\" has been upgraded.\n",
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 1, Chart: ch})},
},
{
@ -152,7 +152,7 @@ func TestUpgradeCmd(t *testing.T) {
args: []string{"crazy-bunny", chartPath},
flags: []string{"-i", "--description", "foo"},
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 1, Chart: ch, Description: "foo"}),
expected: "Release \"crazy-bunny\" has been upgraded. Happy Helming!\n",
expected: "Release \"crazy-bunny\" has been upgraded.\n",
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 1, Chart: ch, Description: "foo"})},
},
{
@ -160,7 +160,7 @@ func TestUpgradeCmd(t *testing.T) {
args: []string{"crazy-bunny", chartPath},
flags: []string{"--wait"},
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 2, Chart: ch2}),
expected: "Release \"crazy-bunny\" has been upgraded. Happy Helming!\n",
expected: "Release \"crazy-bunny\" has been upgraded.\n",
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 2, Chart: ch2})},
},
{
@ -168,7 +168,7 @@ func TestUpgradeCmd(t *testing.T) {
args: []string{"crazy-bunny", chartPath},
flags: []string{"--description", "foo"},
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 2, Chart: ch2}),
expected: "Release \"crazy-bunny\" has been upgraded. Happy Helming!\n",
expected: "Release \"crazy-bunny\" has been upgraded.\n",
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 2, Chart: ch2, Description: "foo"})},
},
{

@ -151,5 +151,5 @@ func formatVersion(v *pb.Version, short bool) string {
if short && v.GitCommit != "" {
return fmt.Sprintf("%s+g%s", v.SemVer, v.GitCommit[:7])
}
return fmt.Sprintf("%#v", v)
return fmt.Sprintf("&version.Version{SemVer:\"%s\", GitCommit:\"%s\", GitTreeState:\"%s\"}", v.SemVer, v.GitCommit, v.GitTreeState)
}

@ -66,6 +66,7 @@ const (
storageMemory = "memory"
storageConfigMap = "configmap"
storageSecret = "secret"
storageSQL = "sql"
traceAddr = ":44136"
@ -74,12 +75,17 @@ const (
)
var (
grpcAddr = flag.String("listen", ":44134", "address:port to listen on")
probeAddr = flag.String("probe-listen", ":44135", "address:port to listen on for probes")
grpcAddr = flag.String("listen", fmt.Sprintf(":%v", environment.DefaultTillerPort), "address:port to listen on")
probeAddr = flag.String("probe-listen", fmt.Sprintf(":%v", environment.DefaultTillerProbePort), "address:port to listen on for probes")
enableProbing = flag.Bool("probe", true, "enable probing over http")
enableTracing = flag.Bool("trace", false, "enable rpc tracing")
store = flag.String("storage", storageConfigMap, "storage driver to use. One of 'configmap', 'memory', or 'secret'")
store = flag.String("storage", storageConfigMap, "storage driver to use. One of 'configmap', 'memory', 'sql' or 'secret'")
sqlDialect = flag.String("sql-dialect", "postgres", "SQL dialect to use (only postgres is supported for now")
sqlConnectionString = flag.String("sql-connection-string", "", "SQL connection string to use")
remoteReleaseModules = flag.Bool("experimental-release", false, "enable experimental release modules")
tlsEnable = flag.Bool("tls", tlsEnableEnvVarDefault(), "enable TLS")
tlsVerify = flag.Bool("tls-verify", tlsVerifyEnvVarDefault(), "enable TLS and verify remote certificate")
keyFile = flag.String("tls-key", tlsDefaultsFromEnv("tls-key"), "path to TLS private key file")
@ -144,6 +150,18 @@ func start() {
env.Releases = storage.Init(secrets)
env.Releases.Log = newLogger("storage").Printf
case storageSQL:
sqlDriver, err := driver.NewSQL(
*sqlDialect,
*sqlConnectionString,
newLogger("storage/driver").Printf,
)
if err != nil {
logger.Fatalf("Cannot initialize SQL storage driver: %v", err)
}
env.Releases = storage.Init(sqlDriver)
env.Releases.Log = newLogger("storage").Printf
}
if *maxHistory > 0 {

@ -182,6 +182,10 @@ Charts repository hosts its charts, so you may want to take a
You can also set up chart repositories using JFrog Artifactory.
Read more about chart repositories with JFrog Artifactory [here](https://www.jfrog.com/confluence/display/RTF/Helm+Chart+Repositories)
### ProGet
Helm chart repositories are supported by ProGet. For more information, visit the [Helm repository documentation](https://inedo.com/support/documentation/proget/feeds/helm) on the Inedo website.
### Github Pages example
In a similar way you can create charts repository using GitHub Pages.

@ -114,6 +114,8 @@ metadata:
# I cannot reference .Chart.Name, but I can do $.Chart.Name
helm.sh/chart: "{{ $.Chart.Name }}-{{ $.Chart.Version }}"
app.kubernetes.io/instance: "{{ $.Release.Name }}"
# Value from appVersion in Chart.yaml
app.kubernetes.io/version: "{{ $.Chart.AppVersion }}"
app.kubernetes.io/managed-by: "{{ $.Release.Service }}"
type: kubernetes.io/tls
data:

@ -191,7 +191,7 @@ Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "stable" chart repository
...Successfully got an update from the "example" chart repository
...Successfully got an update from the "another" chart repository
Update Complete. Happy Helming!
Update Complete.
Saving 2 charts
Downloading apache from repo http://example.com/charts
Downloading mysql from repo http://another.example.com/charts

@ -129,6 +129,7 @@ metadata:
labels:
app.kubernetes.io/managed-by: {{.Release.Service | quote }}
app.kubernetes.io/instance: {{.Release.Name | quote }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
helm.sh/chart: "{{.Chart.Name}}-{{.Chart.Version}}"
annotations:
# This is what defines this resource as a hook. Without this line, the

@ -10,6 +10,7 @@ metadata:
# The "app.kubernetes.io/instance" convention makes it easy to tie a release to all of the
# Kubernetes resources that were created as part of that release.
app.kubernetes.io/instance: {{ .Release.Name | quote }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
# This makes it easy to audit chart usage.
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
app.kubernetes.io/name: {{ template "alpine.name" . }}

@ -21,19 +21,19 @@ Common actions from this point include:
- helm list: list releases of charts
Environment:
$HELM_HOME set an alternative location for Helm files. By default, these are stored in ~/.helm
$HELM_HOST set an alternative Tiller host. The format is host:port
$HELM_NO_PLUGINS disable plugins. Set HELM_NO_PLUGINS=1 to disable plugins.
$TILLER_NAMESPACE set an alternative Tiller namespace (default "kube-system")
$KUBECONFIG set an alternative Kubernetes configuration file (default "~/.kube/config")
$HELM_TLS_CA_CERT path to TLS CA certificate used to verify the Helm client and Tiller server certificates (default "$HELM_HOME/ca.pem")
$HELM_TLS_CERT path to TLS client certificate file for authenticating to Tiller (default "$HELM_HOME/cert.pem")
$HELM_TLS_KEY path to TLS client key file for authenticating to Tiller (default "$HELM_HOME/key.pem")
$HELM_TLS_ENABLE enable TLS connection between Helm and Tiller (default "false")
$HELM_TLS_VERIFY enable TLS connection between Helm and Tiller and verify Tiller server certificate (default "false")
$HELM_TLS_HOSTNAME the hostname or IP address used to verify the Tiller server certificate (default "127.0.0.1")
$HELM_KEY_PASSPHRASE set HELM_KEY_PASSPHRASE to the passphrase of your PGP private key. If set, you will not be prompted for
the passphrase while signing helm charts
- $HELM_HOME: set an alternative location for Helm files. By default, these are stored in ~/.helm
- $HELM_HOST: set an alternative Tiller host. The format is host:port
- $HELM_NO_PLUGINS: disable plugins. Set HELM_NO_PLUGINS=1 to disable plugins.
- $TILLER_NAMESPACE: set an alternative Tiller namespace (default "kube-system")
- $KUBECONFIG: set an alternative Kubernetes configuration file (default "~/.kube/config")
- $HELM_TLS_CA_CERT: path to TLS CA certificate used to verify the Helm client and Tiller server certificates (default "$HELM_HOME/ca.pem")
- $HELM_TLS_CERT: path to TLS client certificate file for authenticating to Tiller (default "$HELM_HOME/cert.pem")
- $HELM_TLS_KEY: path to TLS client key file for authenticating to Tiller (default "$HELM_HOME/key.pem")
- $HELM_TLS_ENABLE: enable TLS connection between Helm and Tiller (default "false")
- $HELM_TLS_VERIFY: enable TLS connection between Helm and Tiller and verify Tiller server certificate (default "false")
- $HELM_TLS_HOSTNAME: the hostname or IP address used to verify the Tiller server certificate (default "127.0.0.1")
- $HELM_KEY_PASSPHRASE: set HELM_KEY_PASSPHRASE to the passphrase of your PGP private key. If set, you will not be prompted for the passphrase while signing helm charts
@ -79,4 +79,4 @@ Environment:
* [helm verify](helm_verify.md) - verify that a chart at the given path has been signed and is valid
* [helm version](helm_version.md) - print the client/server version information
###### Auto generated by spf13/cobra on 4-Feb-2019
###### Auto generated by spf13/cobra on 25-Apr-2019

@ -26,6 +26,7 @@ helm get [flags] RELEASE_NAME
```
-h, --help help for get
--revision int32 get the named release with revision
--template string go template for formatting the output, eg: {{.Release.Name}}
--tls enable TLS for request
--tls-ca-cert string path to TLS CA certificate file (default "$HELM_HOME/ca.pem")
--tls-cert string path to TLS certificate file (default "$HELM_HOME/cert.pem")
@ -54,4 +55,4 @@ helm get [flags] RELEASE_NAME
* [helm get notes](helm_get_notes.md) - displays the notes of the named release
* [helm get values](helm_get_values.md) - download the values file for a named release
###### Auto generated by spf13/cobra on 1-Sep-2018
###### Auto generated by spf13/cobra on 25-Mar-2019

@ -42,4 +42,4 @@ helm verify [flags] PATH
* [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 1-Aug-2018
###### Auto generated by spf13/cobra on 25-Feb-2019

@ -60,21 +60,21 @@ The binary can also be installed via [`scoop`](https://scoop.sh) command-line in
scoop install helm
```
## From Script
### From Script
Helm now has an installer script that will automatically grab the latest version
of the Helm client and [install it locally](https://raw.githubusercontent.com/helm/helm/master/scripts/get).
of the Helm client and [install it locally](https://git.io/get_helm.sh).
You can fetch that script, and then execute it locally. It's well documented so
that you can read through it and understand what it is doing before you run it.
```
$ curl https://raw.githubusercontent.com/helm/helm/master/scripts/get > get_helm.sh
$ curl -LO https://git.io/get_helm.sh
$ chmod 700 get_helm.sh
$ ./get_helm.sh
```
Yes, you can `curl https://raw.githubusercontent.com/helm/helm/master/scripts/get | bash` that if you want to live on the edge.
Yes, you can `curl -L https://git.io/get_helm.sh | bash` that if you want to live on the edge.
### From Canary Builds
@ -353,7 +353,10 @@ in JSON format.
### Storage backends
By default, `tiller` stores release information in `ConfigMaps` in the namespace
where it is running. As of Helm 2.7.0, there is now a beta storage backend that
where it is running.
#### Secret storage backend
As of Helm 2.7.0, there is now a beta storage backend that
uses `Secrets` for storing release information. This was added for additional
security in protecting charts in conjunction with the release of `Secret`
encryption in Kubernetes.
@ -369,6 +372,31 @@ Currently, if you want to switch from the default backend to the secrets
backend, you'll have to do the migration for this on your own. When this backend
graduates from beta, there will be a more official path of migration
#### SQL storage backend
As of Helm 2.14.0 there is now a beta SQL storage backend that stores release
information in an SQL database (only postgres has been tested so far).
Using such a storage backend is particularly useful if your release information
weighs more than 1MB (in which case, it can't be stored in ConfigMaps/Secrets
because of internal limits in Kubernetes' underlying etcd key-value store).
To enable the SQL backend, you'll need to deploy a SQL database and init Tiller
with the following options:
```shell
helm init \
--override \
'spec.template.spec.containers[0].args'='{--storage=sql,--sql-dialect=postgres,--sql-connection-string=postgresql://tiller-postgres:5432/helm?user=helm&password=changeme}'
```
**PRODUCTION NOTES**: it's recommended to change the username and password of
the SQL database in production deployments. Enabling SSL is also a good idea.
Last, but not least, perform regular backups/snapshots of your SQL database.
Currently, if you want to switch from the default backend to the SQL backend,
you'll have to do the migration for this on your own. When this backend
graduates from beta, there will be a more official migration path.
## Conclusion
In most cases, installation is as simple as getting a pre-built `helm` binary

@ -80,7 +80,7 @@ the '\-\-debug' and '\-\-dry\-run' flags can be combined. This will still requir
round\-trip to the Tiller server.
.PP
If \-\-verify is set, the chart MUST have a provenance file, and the provenenace
If \-\-verify is set, the chart MUST have a provenance file, and the provenance
fall MUST pass all verification steps.
.PP

@ -106,7 +106,6 @@ $ helm init --service-account tiller --tiller-namespace tiller-world
$HELM_HOME has been configured at /Users/awesome-user/.helm.
Tiller (the Helm server side component) has been installed into your Kubernetes Cluster.
Happy Helming!
$ helm install nginx --tiller-namespace tiller-world --namespace tiller-world
NAME: wayfaring-yak

@ -19,6 +19,7 @@ or [pull request](https://github.com/helm/helm/pulls).
- [Writing a Helm Chart](https://www.influxdata.com/packaged-kubernetes-deployments-writing-helm-chart/)
- [A basic walk through Kubernetes Helm](https://github.com/muffin87/helm-tutorial)
- [Tillerless Helm v2](https://rimusz.net/tillerless-helm/)
- [Generating Certificate Authorities and Certificates using Terraform](https://github.com/jbussdieker/tiller-ssl-terraform)
## Video, Audio, and Podcast
@ -68,6 +69,7 @@ Tools layered on top of Helm or Tiller.
- [Armada](https://github.com/att-comdev/armada) - Manage prefixed releases throughout various Kubernetes namespaces, and removes completed jobs for complex deployments. Used by the [Openstack-Helm](https://github.com/openstack/openstack-helm) team.
- [ChartMuseum](https://github.com/chartmuseum/chartmuseum) - Helm Chart Repository with support for Amazon S3 and Google Cloud Storage
- [Chartify](https://github.com/appscode/chartify) - Generate Helm charts from existing Kubernetes resources.
- [Cloudsmith](https://cloudsmith.io/l/helm-repository/) - Fully managed SaaS offering private Helm Chart Repositories
- [Codefresh](https://codefresh.io) - Kubernetes native CI/CD and management platform with UI dashboards for managing Helm charts and releases
- [Cog](https://github.com/ohaiwalt/cog-helm) - Helm chart to deploy Cog on Kubernetes
- [Drone.io Helm Plugin](http://plugins.drone.io/ipedrazas/drone-helm/) - Run Helm inside of the Drone CI/CD system

@ -147,6 +147,24 @@ git add .
git commit -m "bump version to $RELEASE_CANDIDATE_NAME"
```
This will update it for the $RELEASE_BRANCH_NAME only. You will also need to pull
this change into the master branch for when the next release is being created.
```shell
# get the last commit id i.e. commit to bump the version
git log --format="%H" -n 1
# create new branch off master
git checkout master
git checkout -b bump-version-<release_version>
# cherry pick the commit using id from first command
git cherry-pick -x <commit-id>
# commit the change
git push origin bump-version-<release-version>
```
## 3. Commit and Push the Release Branch
In order for others to start testing, we can now push the release branch

@ -42,6 +42,8 @@ on getting ready within a small amount of time. For production configurations,
we urge readers to read [the official documentation](https://www.openssl.org) and
consult other resources.
There are other alternative ways to generating SSL CAs in addition to `openssl`, for example Terraform. They are not documented here but you can find links to these alternative means in [Related Projects and Documentation](https://helm.sh/docs/related/).
### Generate a Certificate Authority
The simplest way to generate a certificate authority is to run two commands:

@ -359,7 +359,7 @@ update things that have changed since the last release.
```console
$ helm upgrade -f panda.yaml happy-panda stable/mariadb
Fetched stable/mariadb-0.3.0.tgz to /Users/mattbutcher/Code/Go/src/k8s.io/helm/mariadb-0.3.0.tgz
happy-panda has been upgraded. Happy Helming!
happy-panda has been upgraded.
Last Deployed: Wed Sep 28 12:47:54 2016
Namespace: default
Status: DEPLOYED

41
glide.lock generated

@ -1,5 +1,5 @@
hash: 9a8f0b6c906f605bb879fbcdf0c122096f7698fe6a975ec4e6648f2ee85fce3e
updated: 2019-03-26T10:33:38.977361532-07:00
hash: 7571b58bbda7d85993d2b737b50d0c52f5fadce0c63e7fac064bc0a99faaefab
updated: 2019-05-07T10:43:27.329085-04:00
imports:
- name: cloud.google.com/go
version: 3b1ae45394a234c385be014e9a488f2bb6eef821
@ -173,10 +173,18 @@ imports:
version: 9316a62528ac99aaecb4e47eadd6dc8aa6533d58
- name: github.com/inconshreveable/mousetrap
version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75
- name: github.com/jmoiron/sqlx
version: d161d7a76b5661016ad0b085869f77fd410f3e6a
subpackages:
- reflectx
- name: github.com/json-iterator/go
version: ab8a2e0c74be9d3be70b3184d9acc634935ded82
- name: github.com/liggitt/tabwriter
version: 89fcab3d43de07060e4fd4c1547430ed57e87f24
- name: github.com/lib/pq
version: 88edab0803230a3898347e77b474f8c1820a1f20
subpackages:
- oid
- name: github.com/mailru/easyjson
version: 2f5df55504ebc322e4d52d34df6a1f5b503bf26d
subpackages:
@ -188,7 +196,7 @@ imports:
- name: github.com/Masterminds/goutils
version: 41ac8693c5c10a92ea1ff5ac3a7f95646f6123b0
- name: github.com/Masterminds/semver
version: 517734cc7d6470c0d07130e40fd40bdeb9bcd3fd
version: c7af12943936e8c39859482e61f0574c2fd7fc75
- name: github.com/Masterminds/sprig
version: 9f8fceff796fb9f4e992cd2bece016be0121ab74
- name: github.com/Masterminds/vcs
@ -212,9 +220,10 @@ imports:
- name: github.com/pkg/errors
version: 645ef00459ed84a119197bfb8d8205042c6df63d
- name: github.com/prometheus/client_golang
version: c5b7fccd204277076155f10851dad72b76a49317
version: 505eaef017263e299324067d40ca2c48f6a2cf50
subpackages:
- prometheus
- prometheus/internal
- prometheus/promhttp
- name: github.com/prometheus/client_model
version: fa8ad6fec33561be4280a8f0514318c79d7f6cb6
@ -234,6 +243,10 @@ imports:
version: 8a290539e2e8629dbc4e6bad948158f790ec31f4
- name: github.com/PuerkitoBio/urlesc
version: 5bd2802263f21d8788851d5305584c82a5c75d7e
- name: github.com/rubenv/sql-migrate
version: 1007f53448d75fe14190968f5de4d95ed63ebb83
subpackages:
- sqlparse
- name: github.com/russross/blackfriday
version: 300106c228d52c8941d4b3de6054a6062a86dda3
- name: github.com/shurcooL/sanitized_anchor_name
@ -365,6 +378,8 @@ imports:
- stats
- status
- tap
- name: gopkg.in/gorp.v1
version: 6a667da9c028871f98598d85413e3fc4c6daa52e
- name: gopkg.in/inf.v0
version: 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4
- name: gopkg.in/square/go-jose.v2
@ -376,7 +391,7 @@ imports:
- name: gopkg.in/yaml.v2
version: 5420a8b6744d3b0345ab293f6fcba19c978f1183
- name: k8s.io/api
version: 40a48860b5abbba9aa891b02b32da429b08d96a0
version: 6e4e0e4f393bf5e8bbff570acd13217aa5a770cd
subpackages:
- admission/v1beta1
- admissionregistration/v1beta1
@ -417,11 +432,13 @@ imports:
- storage/v1alpha1
- storage/v1beta1
- name: k8s.io/apiextensions-apiserver
version: 53c4693659ed354d76121458fb819202dd1635fa
version: 727a075fdec8319bf095330e344b3ccc668abc73
subpackages:
- pkg/apis/apiextensions
- pkg/apis/apiextensions/v1beta1
- pkg/features
- name: k8s.io/apimachinery
version: d7deff9243b165ee192f5551710ea4285dcfd615
version: 6a84e37a896db9780c75367af8d2ed2bb944022e
subpackages:
- pkg/api/equality
- pkg/api/errors
@ -477,7 +494,7 @@ imports:
- third_party/forked/golang/netutil
- third_party/forked/golang/reflect
- name: k8s.io/apiserver
version: 8b27c41bdbb11ff103caa673315e097bf0289171
version: 1ec86e4da56ce0573788fc12bb3a5530600c0e5d
subpackages:
- pkg/authentication/authenticator
- pkg/authentication/serviceaccount
@ -485,7 +502,7 @@ imports:
- pkg/features
- pkg/util/feature
- name: k8s.io/cli-runtime
version: 2899ed30580fdbc8286718edb4382b529463099d
version: d644b00f3b79346b7627329269bb25f2135f941c
subpackages:
- pkg/genericclioptions
- pkg/kustomize
@ -500,7 +517,7 @@ imports:
- pkg/printers
- pkg/resource
- name: k8s.io/client-go
version: 6ee68ca5fd8355d024d02f9db0b3b667e8357a0f
version: 1a26190bd76a9017e289958b9fba936430aa3704
subpackages:
- discovery
- discovery/cached/disk
@ -644,7 +661,7 @@ imports:
- pkg/util/proto/testing
- pkg/util/proto/validation
- name: k8s.io/kubernetes
version: b805719a99126e54bcbc0a3d9ee8a45cd7e85632
version: b7394102d6ef778017f2ca4046abbaa23b88c290
subpackages:
- pkg/api/legacyscheme
- pkg/api/service
@ -804,6 +821,8 @@ imports:
subpackages:
- sortorder
testImports:
- name: github.com/DATA-DOG/go-sqlmock
version: 472e287dbafe67e526a3797165b64cb14f34705a
- name: github.com/pmezard/go-difflib
version: 5d4384ee4fb2527b0a1256a821ebfc92f91efefc
subpackages:

@ -6,7 +6,6 @@ import:
- package: golang.org/x/sync
subpackages:
- semaphore
# This is temporary and can probably be removed the next time gRPC is updated
- package: golang.org/x/sys
version: b90733256f2e882e81d52f9126de08df5615afd9
subpackages:
@ -17,14 +16,13 @@ import:
- package: github.com/spf13/pflag
version: ~1.0.1
- package: github.com/Masterminds/vcs
# Pin version of mergo that is compatible with both sprig and Kubernetes
- package: github.com/imdario/mergo
version: v0.3.5
- package: github.com/Masterminds/sprig
version: ^2.19.0
- package: github.com/ghodss/yaml
- package: github.com/Masterminds/semver
version: ~1.3.1
version: ~1.4.2
- package: github.com/technosophos/moniker
version: ~0.2
- package: github.com/golang/protobuf
@ -48,27 +46,32 @@ import:
- package: github.com/BurntSushi/toml
version: ~0.3.0
- package: github.com/prometheus/client_golang
version: 0.8.0
version: 0.9.2
- package: github.com/grpc-ecosystem/go-grpc-prometheus
- package: k8s.io/kubernetes
version: release-1.14
version: v1.14.1
- package: k8s.io/client-go
version: kubernetes-1.14.0
version: kubernetes-1.14.1
- package: k8s.io/api
version: kubernetes-1.14.0
version: kubernetes-1.14.1
- package: k8s.io/apimachinery
version: kubernetes-1.14.0
version: kubernetes-1.14.1
- package: k8s.io/apiserver
version: kubernetes-1.14.0
version: kubernetes-1.14.1
- package: k8s.io/cli-runtime
version: kubernetes-1.14.0
version: kubernetes-1.14.1
- package: k8s.io/apiextensions-apiserver
version: kubernetes-1.14.0
version: kubernetes-1.14.1
- package: github.com/cyphar/filepath-securejoin
version: ^0.2.1
- package: github.com/jmoiron/sqlx
version: ^1.2.0
- package: github.com/rubenv/sql-migrate
testImports:
- package: github.com/stretchr/testify
version: ^1.1.4
subpackages:
- assert
- package: github.com/DATA-DOG/go-sqlmock
version: ^1.3.2

@ -63,6 +63,7 @@ image:
tag: stable
pullPolicy: IfNotPresent
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
@ -134,10 +135,7 @@ kind: Ingress
metadata:
name: {{ $fullName }}
labels:
app.kubernetes.io/name: {{ include "<CHARTNAME>.name" . }}
helm.sh/chart: {{ include "<CHARTNAME>.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{ include "<CHARTNAME>.labels" . | indent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
@ -173,10 +171,7 @@ kind: Deployment
metadata:
name: {{ include "<CHARTNAME>.fullname" . }}
labels:
app.kubernetes.io/name: {{ include "<CHARTNAME>.name" . }}
helm.sh/chart: {{ include "<CHARTNAME>.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{ include "<CHARTNAME>.labels" . | indent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
@ -189,6 +184,10 @@ spec:
app.kubernetes.io/name: {{ include "<CHARTNAME>.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
@ -226,10 +225,7 @@ kind: Service
metadata:
name: {{ include "<CHARTNAME>.fullname" . }}
labels:
app.kubernetes.io/name: {{ include "<CHARTNAME>.name" . }}
helm.sh/chart: {{ include "<CHARTNAME>.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{ include "<CHARTNAME>.labels" . | indent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
@ -297,6 +293,19 @@ Create chart name and version as used by the chart label.
{{- define "<CHARTNAME>.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Common labels
*/}}
{{- define "<CHARTNAME>.labels" -}}
app.kubernetes.io/name: {{ include "<CHARTNAME>.name" . }}
helm.sh/chart: {{ include "<CHARTNAME>.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}
`
const defaultTestConnection = `apiVersion: v1
@ -304,10 +313,7 @@ kind: Pod
metadata:
name: "{{ include "<CHARTNAME>.fullname" . }}-test-connection"
labels:
app.kubernetes.io/name: {{ include "<CHARTNAME>.name" . }}
helm.sh/chart: {{ include "<CHARTNAME>.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{ include "<CHARTNAME>.labels" . | indent 4 }}
annotations:
"helm.sh/hook": test-success
spec:

@ -465,7 +465,7 @@ func (m *Manager) parallelRepoUpdate(repos []*repo.Entry) error {
}(r)
}
wg.Wait()
fmt.Fprintln(out, "Update Complete. ⎈Happy Helming!⎈")
fmt.Fprintln(out, "Update Complete.")
return nil
}

@ -26,7 +26,8 @@ import (
rls "k8s.io/helm/pkg/proto/hapi/services"
)
const cmInputTemplate = `kind: ConfigMap
const (
cmInputTemplate = `kind: ConfigMap
apiVersion: v1
metadata:
name: example
@ -34,7 +35,7 @@ data:
Release:
{{.Release | toYaml | indent 4}}
`
const cmOutputTemplate = `
cmOutputTemplate = `
---
# Source: installChart/templates/cm.yaml
kind: ConfigMap
@ -53,6 +54,7 @@ data:
seconds: 242085845
`
)
var installChart *chart.Chart

@ -27,6 +27,7 @@ import (
"k8s.io/client-go/rest"
"k8s.io/helm/pkg/kube"
"k8s.io/helm/pkg/tiller/environment"
)
var (
@ -39,8 +40,7 @@ func New(namespace string, client kubernetes.Interface, config *rest.Config) (*k
if err != nil {
return nil, err
}
const tillerPort = 44134
t := kube.NewTunnel(client.CoreV1().RESTClient(), config, namespace, podName, tillerPort)
t := kube.NewTunnel(client.CoreV1().RESTClient(), config, namespace, podName, environment.DefaultTillerPort)
return t, t.ForwardPort()
}

@ -20,14 +20,14 @@ import (
"k8s.io/helm/pkg/proto/hapi/release"
)
const (
// HookAnno is the label name for a hook
const HookAnno = "helm.sh/hook"
HookAnno = "helm.sh/hook"
// HookWeightAnno is the label name for a hook weight
const HookWeightAnno = "helm.sh/hook-weight"
HookWeightAnno = "helm.sh/hook-weight"
// HookDeleteAnno is the label name for the delete policy for a hook
const HookDeleteAnno = "helm.sh/hook-delete-policy"
HookDeleteAnno = "helm.sh/hook-delete-policy"
)
// Types of hooks
const (

@ -37,6 +37,7 @@ import (
batch "k8s.io/api/batch/v1"
v1 "k8s.io/api/core/v1"
extv1beta1 "k8s.io/api/extensions/v1beta1"
apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
apiequality "k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -45,6 +46,7 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/strategicpatch"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/resource"
@ -76,6 +78,12 @@ func New(getter genericclioptions.RESTClientGetter) *Client {
if getter == nil {
getter = genericclioptions.NewConfigFlags(true)
}
err := apiextv1beta1.AddToScheme(scheme.Scheme)
if err != nil {
panic(err)
}
return &Client{
Factory: cmdutil.NewFactory(getter),
Log: nopLogger,
@ -142,8 +150,8 @@ func (c *Client) BuildUnstructured(namespace string, reader io.Reader) (Result,
ContinueOnError().
NamespaceParam(namespace).
DefaultNamespace().
Stream(reader, "").
Schema(c.validator()).
Stream(reader, "").
Flatten().
Do().Infos()
return result, scrubValidationError(err)
@ -488,6 +496,55 @@ func (c *Client) WatchUntilReady(namespace string, reader io.Reader, timeout int
return perform(infos, c.watchTimeout(time.Duration(timeout)*time.Second))
}
// WatchUntilCRDEstablished polls the given CRD until it reaches the established
// state. A CRD needs to reach the established state before CRs can be created.
//
// If a naming conflict condition is found, this function will return an error.
func (c *Client) WaitUntilCRDEstablished(reader io.Reader, timeout time.Duration) error {
infos, err := c.BuildUnstructured(metav1.NamespaceAll, reader)
if err != nil {
return err
}
return perform(infos, c.pollCRDEstablished(timeout))
}
func (c *Client) pollCRDEstablished(t time.Duration) ResourceActorFunc {
return func(info *resource.Info) error {
return c.pollCRDUntilEstablished(t, info)
}
}
func (c *Client) pollCRDUntilEstablished(timeout time.Duration, info *resource.Info) error {
return wait.PollImmediate(time.Second, timeout, func() (bool, error) {
err := info.Get()
if err != nil {
return false, fmt.Errorf("unable to get CRD: %v", err)
}
crd := &apiextv1beta1.CustomResourceDefinition{}
err = scheme.Scheme.Convert(info.Object, crd, nil)
if err != nil {
return false, fmt.Errorf("unable to convert to CRD type: %v", err)
}
for _, cond := range crd.Status.Conditions {
switch cond.Type {
case apiextv1beta1.Established:
if cond.Status == apiextv1beta1.ConditionTrue {
return true, nil
}
case apiextv1beta1.NamesAccepted:
if cond.Status == apiextv1beta1.ConditionFalse {
return false, fmt.Errorf("naming conflict detected for CRD %s", crd.GetName())
}
}
}
return false, nil
})
}
func perform(infos Result, fn ResourceActorFunc) error {
if len(infos) == 0 {
return ErrNoObjectsVisited

@ -24,8 +24,10 @@ import (
"sort"
"strings"
"testing"
"time"
v1 "k8s.io/api/core/v1"
"k8s.io/api/core/v1"
apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
@ -33,15 +35,35 @@ import (
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest/fake"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
kubectlscheme "k8s.io/kubernetes/pkg/kubectl/scheme"
)
func init() {
err := apiextv1beta1.AddToScheme(scheme.Scheme)
if err != nil {
panic(err)
}
// Tiller use the scheme from go-client, but the cmdtesting
// package used here is hardcoded to use the scheme from
// kubectl. So for testing, we need to add the CustomResourceDefinition
// type to both schemes.
err = apiextv1beta1.AddToScheme(kubectlscheme.Scheme)
if err != nil {
panic(err)
}
}
var (
codec = scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
unstructuredSerializer = resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer
)
func getCodec() runtime.Codec {
return scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
}
func objBody(obj runtime.Object) io.ReadCloser {
return ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(codec, obj))))
return ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(getCodec(), obj))))
}
func newPod(name string) v1.Pod {
@ -103,7 +125,7 @@ func notFoundBody() *metav1.Status {
func newResponse(code int, obj runtime.Object) (*http.Response, error) {
header := http.Header{}
header.Set("Content-Type", runtime.ContentTypeJSON)
body := ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(codec, obj))))
body := ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(getCodec(), obj))))
return &http.Response{StatusCode: code, Header: header, Body: body}, nil
}
@ -434,6 +456,88 @@ func TestResourceSortOrder(t *testing.T) {
}
}
func TestWaitUntilCRDEstablished(t *testing.T) {
testCases := map[string]struct {
conditions []apiextv1beta1.CustomResourceDefinitionCondition
returnConditionsAfter int
success bool
}{
"crd reaches established state after 2 requests": {
conditions: []apiextv1beta1.CustomResourceDefinitionCondition{
{
Type: apiextv1beta1.Established,
Status: apiextv1beta1.ConditionTrue,
},
},
returnConditionsAfter: 2,
success: true,
},
"crd does not reach established state before timeout": {
conditions: []apiextv1beta1.CustomResourceDefinitionCondition{},
returnConditionsAfter: 100,
success: false,
},
"crd name is not accepted": {
conditions: []apiextv1beta1.CustomResourceDefinitionCondition{
{
Type: apiextv1beta1.NamesAccepted,
Status: apiextv1beta1.ConditionFalse,
},
},
returnConditionsAfter: 1,
success: false,
},
}
for tn, tc := range testCases {
func(name string) {
c := newTestClient()
defer c.Cleanup()
crdWithoutConditions := newCrdWithStatus("name", apiextv1beta1.CustomResourceDefinitionStatus{})
crdWithConditions := newCrdWithStatus("name", apiextv1beta1.CustomResourceDefinitionStatus{
Conditions: tc.conditions,
})
requestCount := 0
c.TestFactory.UnstructuredClient = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: "v1"},
NegotiatedSerializer: unstructuredSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
var crd apiextv1beta1.CustomResourceDefinition
if requestCount < tc.returnConditionsAfter {
crd = crdWithoutConditions
} else {
crd = crdWithConditions
}
requestCount += 1
return newResponse(200, &crd)
}),
}
err := c.WaitUntilCRDEstablished(strings.NewReader(crdManifest), 5*time.Second)
if err != nil && tc.success {
t.Errorf("%s: expected no error, but got %v", name, err)
}
if err == nil && !tc.success {
t.Errorf("%s: expected error, but didn't get one", name)
}
}(tn)
}
}
func newCrdWithStatus(name string, status apiextv1beta1.CustomResourceDefinitionStatus) apiextv1beta1.CustomResourceDefinition {
crd := apiextv1beta1.CustomResourceDefinition{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: metav1.NamespaceDefault,
},
Spec: apiextv1beta1.CustomResourceDefinitionSpec{},
Status: status,
}
return crd
}
func TestPerform(t *testing.T) {
tests := []struct {
name string
@ -701,3 +805,41 @@ spec:
ports:
- containerPort: 80
`
const crdManifest = `
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
creationTimestamp: null
labels:
controller-tools.k8s.io: "1.0"
name: applications.app.k8s.io
spec:
group: app.k8s.io
names:
kind: Application
plural: applications
scope: Namespaced
validation:
openAPIV3Schema:
properties:
apiVersion:
description: 'Description'
type: string
kind:
description: 'Kind'
type: string
metadata:
type: object
spec:
type: object
status:
type: object
version: v1beta1
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []
`

@ -16,8 +16,9 @@ limitations under the License.
package kube
const (
// ResourcePolicyAnno is the annotation name for a resource policy
const ResourcePolicyAnno = "helm.sh/resource-policy"
ResourcePolicyAnno = "helm.sh/resource-policy"
// deletePolicy is the resource policy type for delete
//
@ -25,7 +26,8 @@ const ResourcePolicyAnno = "helm.sh/resource-policy"
// resource deletion behavior, for example when overriding a chart's
// default annotations. Any other value allows resources to skip being
// deleted during an uninstallRelease action.
const deletePolicy = "delete"
deletePolicy = "delete"
)
// ResourcePolicyIsKeep accepts a map of Kubernetes resource annotations and
// returns true if the resource should be kept, otherwise false if it is safe

@ -26,13 +26,14 @@ import (
var values = []byte{}
const namespace = "testNamespace"
const strict = false
const badChartDir = "rules/testdata/badchartfile"
const badValuesFileDir = "rules/testdata/badvaluesfile"
const badYamlFileDir = "rules/testdata/albatross"
const goodChartDir = "rules/testdata/goodone"
const (
namespace = "testNamespace"
strict = false
badChartDir = "rules/testdata/badchartfile"
badValuesFileDir = "rules/testdata/badvaluesfile"
badYamlFileDir = "rules/testdata/albatross"
goodChartDir = "rules/testdata/goodone"
)
func TestBadChart(t *testing.T) {
m := All(badChartDir, values, namespace, strict).Messages

@ -25,7 +25,11 @@ import (
"k8s.io/helm/pkg/lint/support"
)
const templateTestBasedir = "./testdata/albatross"
const (
strict = false
namespace = "testNamespace"
templateTestBasedir = "./testdata/albatross"
)
func TestValidateAllowedExtension(t *testing.T) {
var failTest = []string{"/foo", "/test.toml"}
@ -46,9 +50,6 @@ func TestValidateAllowedExtension(t *testing.T) {
var values = []byte("nameOverride: ''\nhttpPort: 80")
const namespace = "testNamespace"
const strict = false
func TestTemplateParsing(t *testing.T) {
linter := support.Linter{ChartDir: templateTestBasedir}
Templates(&linter, values, namespace, strict)

@ -1,29 +1,12 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: hapi/chart/chart.proto
/*
Package chart is a generated protocol buffer package.
It is generated from these files:
hapi/chart/chart.proto
hapi/chart/config.proto
hapi/chart/metadata.proto
hapi/chart/template.proto
It has these top-level messages:
Chart
Config
Value
Maintainer
Metadata
Template
*/
package chart
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import google_protobuf "github.com/golang/protobuf/ptypes/any"
import any "github.com/golang/protobuf/ptypes/any"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
@ -40,22 +23,44 @@ const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
// optionally parameterizable templates, and zero or more charts (dependencies).
type Chart struct {
// Contents of the Chartfile.
Metadata *Metadata `protobuf:"bytes,1,opt,name=metadata" json:"metadata,omitempty"`
Metadata *Metadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"`
// Templates for this chart.
Templates []*Template `protobuf:"bytes,2,rep,name=templates" json:"templates,omitempty"`
Templates []*Template `protobuf:"bytes,2,rep,name=templates,proto3" json:"templates,omitempty"`
// Charts that this chart depends on.
Dependencies []*Chart `protobuf:"bytes,3,rep,name=dependencies" json:"dependencies,omitempty"`
Dependencies []*Chart `protobuf:"bytes,3,rep,name=dependencies,proto3" json:"dependencies,omitempty"`
// Default config for this template.
Values *Config `protobuf:"bytes,4,opt,name=values" json:"values,omitempty"`
Values *Config `protobuf:"bytes,4,opt,name=values,proto3" json:"values,omitempty"`
// Miscellaneous files in a chart archive,
// e.g. README, LICENSE, etc.
Files []*google_protobuf.Any `protobuf:"bytes,5,rep,name=files" json:"files,omitempty"`
Files []*any.Any `protobuf:"bytes,5,rep,name=files,proto3" json:"files,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Chart) Reset() { *m = Chart{} }
func (m *Chart) String() string { return proto.CompactTextString(m) }
func (*Chart) ProtoMessage() {}
func (*Chart) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (*Chart) Descriptor() ([]byte, []int) {
return fileDescriptor_chart_829b474cf208a7f0, []int{0}
}
func (m *Chart) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Chart.Unmarshal(m, b)
}
func (m *Chart) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Chart.Marshal(b, m, deterministic)
}
func (dst *Chart) XXX_Merge(src proto.Message) {
xxx_messageInfo_Chart.Merge(dst, src)
}
func (m *Chart) XXX_Size() int {
return xxx_messageInfo_Chart.Size(m)
}
func (m *Chart) XXX_DiscardUnknown() {
xxx_messageInfo_Chart.DiscardUnknown(m)
}
var xxx_messageInfo_Chart proto.InternalMessageInfo
func (m *Chart) GetMetadata() *Metadata {
if m != nil {
@ -85,7 +90,7 @@ func (m *Chart) GetValues() *Config {
return nil
}
func (m *Chart) GetFiles() []*google_protobuf.Any {
func (m *Chart) GetFiles() []*any.Any {
if m != nil {
return m.Files
}
@ -96,9 +101,9 @@ func init() {
proto.RegisterType((*Chart)(nil), "hapi.chart.Chart")
}
func init() { proto.RegisterFile("hapi/chart/chart.proto", fileDescriptor0) }
func init() { proto.RegisterFile("hapi/chart/chart.proto", fileDescriptor_chart_829b474cf208a7f0) }
var fileDescriptor0 = []byte{
var fileDescriptor_chart_829b474cf208a7f0 = []byte{
// 242 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0xb1, 0x4e, 0xc3, 0x30,
0x10, 0x86, 0x15, 0x4a, 0x0a, 0x1c, 0x2c, 0x58, 0x08, 0x4c, 0xa7, 0x8a, 0x09, 0x75, 0x70, 0x50,

@ -12,16 +12,44 @@ var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
// Config supplies values to the parametrizable templates of a chart.
type Config struct {
Raw string `protobuf:"bytes,1,opt,name=raw" json:"raw,omitempty"`
Values map[string]*Value `protobuf:"bytes,2,rep,name=values" json:"values,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
Raw string `protobuf:"bytes,1,opt,name=raw,proto3" json:"raw,omitempty"`
Values map[string]*Value `protobuf:"bytes,2,rep,name=values,proto3" json:"values,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Config) Reset() { *m = Config{} }
func (m *Config) String() string { return proto.CompactTextString(m) }
func (*Config) ProtoMessage() {}
func (*Config) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{0} }
func (*Config) Descriptor() ([]byte, []int) {
return fileDescriptor_config_332ead17c4feed84, []int{0}
}
func (m *Config) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Config.Unmarshal(m, b)
}
func (m *Config) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Config.Marshal(b, m, deterministic)
}
func (dst *Config) XXX_Merge(src proto.Message) {
xxx_messageInfo_Config.Merge(dst, src)
}
func (m *Config) XXX_Size() int {
return xxx_messageInfo_Config.Size(m)
}
func (m *Config) XXX_DiscardUnknown() {
xxx_messageInfo_Config.DiscardUnknown(m)
}
var xxx_messageInfo_Config proto.InternalMessageInfo
func (m *Config) GetRaw() string {
if m != nil {
@ -39,13 +67,35 @@ func (m *Config) GetValues() map[string]*Value {
// Value describes a configuration value as a string.
type Value struct {
Value string `protobuf:"bytes,1,opt,name=value" json:"value,omitempty"`
Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Value) Reset() { *m = Value{} }
func (m *Value) String() string { return proto.CompactTextString(m) }
func (*Value) ProtoMessage() {}
func (*Value) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{1} }
func (*Value) Descriptor() ([]byte, []int) {
return fileDescriptor_config_332ead17c4feed84, []int{1}
}
func (m *Value) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Value.Unmarshal(m, b)
}
func (m *Value) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Value.Marshal(b, m, deterministic)
}
func (dst *Value) XXX_Merge(src proto.Message) {
xxx_messageInfo_Value.Merge(dst, src)
}
func (m *Value) XXX_Size() int {
return xxx_messageInfo_Value.Size(m)
}
func (m *Value) XXX_DiscardUnknown() {
xxx_messageInfo_Value.DiscardUnknown(m)
}
var xxx_messageInfo_Value proto.InternalMessageInfo
func (m *Value) GetValue() string {
if m != nil {
@ -56,12 +106,13 @@ func (m *Value) GetValue() string {
func init() {
proto.RegisterType((*Config)(nil), "hapi.chart.Config")
proto.RegisterMapType((map[string]*Value)(nil), "hapi.chart.Config.ValuesEntry")
proto.RegisterType((*Value)(nil), "hapi.chart.Value")
}
func init() { proto.RegisterFile("hapi/chart/config.proto", fileDescriptor1) }
func init() { proto.RegisterFile("hapi/chart/config.proto", fileDescriptor_config_332ead17c4feed84) }
var fileDescriptor1 = []byte{
var fileDescriptor_config_332ead17c4feed84 = []byte{
// 182 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0xcf, 0x48, 0x2c, 0xc8,
0xd4, 0x4f, 0xce, 0x48, 0x2c, 0x2a, 0xd1, 0x4f, 0xce, 0xcf, 0x4b, 0xcb, 0x4c, 0xd7, 0x2b, 0x28,

@ -12,6 +12,12 @@ var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type Metadata_Engine int32
const (
@ -31,22 +37,46 @@ var Metadata_Engine_value = map[string]int32{
func (x Metadata_Engine) String() string {
return proto.EnumName(Metadata_Engine_name, int32(x))
}
func (Metadata_Engine) EnumDescriptor() ([]byte, []int) { return fileDescriptor2, []int{1, 0} }
func (Metadata_Engine) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_metadata_d6c714c73a051dcb, []int{1, 0}
}
// Maintainer describes a Chart maintainer.
type Maintainer struct {
// Name is a user name or organization name
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
// Email is an optional email address to contact the named maintainer
Email string `protobuf:"bytes,2,opt,name=email" json:"email,omitempty"`
Email string `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"`
// Url is an optional URL to an address for the named maintainer
Url string `protobuf:"bytes,3,opt,name=url" json:"url,omitempty"`
Url string `protobuf:"bytes,3,opt,name=url,proto3" json:"url,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Maintainer) Reset() { *m = Maintainer{} }
func (m *Maintainer) String() string { return proto.CompactTextString(m) }
func (*Maintainer) ProtoMessage() {}
func (*Maintainer) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{0} }
func (*Maintainer) Descriptor() ([]byte, []int) {
return fileDescriptor_metadata_d6c714c73a051dcb, []int{0}
}
func (m *Maintainer) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Maintainer.Unmarshal(m, b)
}
func (m *Maintainer) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Maintainer.Marshal(b, m, deterministic)
}
func (dst *Maintainer) XXX_Merge(src proto.Message) {
xxx_messageInfo_Maintainer.Merge(dst, src)
}
func (m *Maintainer) XXX_Size() int {
return xxx_messageInfo_Maintainer.Size(m)
}
func (m *Maintainer) XXX_DiscardUnknown() {
xxx_messageInfo_Maintainer.DiscardUnknown(m)
}
var xxx_messageInfo_Maintainer proto.InternalMessageInfo
func (m *Maintainer) GetName() string {
if m != nil {
@ -74,47 +104,69 @@ func (m *Maintainer) GetUrl() string {
// Spec: https://k8s.io/helm/blob/master/docs/design/chart_format.md#the-chart-file
type Metadata struct {
// The name of the chart
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
// The URL to a relevant project page, git repo, or contact person
Home string `protobuf:"bytes,2,opt,name=home" json:"home,omitempty"`
Home string `protobuf:"bytes,2,opt,name=home,proto3" json:"home,omitempty"`
// Source is the URL to the source code of this chart
Sources []string `protobuf:"bytes,3,rep,name=sources" json:"sources,omitempty"`
Sources []string `protobuf:"bytes,3,rep,name=sources,proto3" json:"sources,omitempty"`
// A SemVer 2 conformant version string of the chart
Version string `protobuf:"bytes,4,opt,name=version" json:"version,omitempty"`
Version string `protobuf:"bytes,4,opt,name=version,proto3" json:"version,omitempty"`
// A one-sentence description of the chart
Description string `protobuf:"bytes,5,opt,name=description" json:"description,omitempty"`
Description string `protobuf:"bytes,5,opt,name=description,proto3" json:"description,omitempty"`
// A list of string keywords
Keywords []string `protobuf:"bytes,6,rep,name=keywords" json:"keywords,omitempty"`
Keywords []string `protobuf:"bytes,6,rep,name=keywords,proto3" json:"keywords,omitempty"`
// A list of name and URL/email address combinations for the maintainer(s)
Maintainers []*Maintainer `protobuf:"bytes,7,rep,name=maintainers" json:"maintainers,omitempty"`
Maintainers []*Maintainer `protobuf:"bytes,7,rep,name=maintainers,proto3" json:"maintainers,omitempty"`
// The name of the template engine to use. Defaults to 'gotpl'.
Engine string `protobuf:"bytes,8,opt,name=engine" json:"engine,omitempty"`
Engine string `protobuf:"bytes,8,opt,name=engine,proto3" json:"engine,omitempty"`
// The URL to an icon file.
Icon string `protobuf:"bytes,9,opt,name=icon" json:"icon,omitempty"`
Icon string `protobuf:"bytes,9,opt,name=icon,proto3" json:"icon,omitempty"`
// The API Version of this chart.
ApiVersion string `protobuf:"bytes,10,opt,name=apiVersion" json:"apiVersion,omitempty"`
ApiVersion string `protobuf:"bytes,10,opt,name=apiVersion,proto3" json:"apiVersion,omitempty"`
// The condition to check to enable chart
Condition string `protobuf:"bytes,11,opt,name=condition" json:"condition,omitempty"`
Condition string `protobuf:"bytes,11,opt,name=condition,proto3" json:"condition,omitempty"`
// The tags to check to enable chart
Tags string `protobuf:"bytes,12,opt,name=tags" json:"tags,omitempty"`
Tags string `protobuf:"bytes,12,opt,name=tags,proto3" json:"tags,omitempty"`
// The version of the application enclosed inside of this chart.
AppVersion string `protobuf:"bytes,13,opt,name=appVersion" json:"appVersion,omitempty"`
AppVersion string `protobuf:"bytes,13,opt,name=appVersion,proto3" json:"appVersion,omitempty"`
// Whether or not this chart is deprecated
Deprecated bool `protobuf:"varint,14,opt,name=deprecated" json:"deprecated,omitempty"`
Deprecated bool `protobuf:"varint,14,opt,name=deprecated,proto3" 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"`
TillerVersion string `protobuf:"bytes,15,opt,name=tillerVersion,proto3" json:"tillerVersion,omitempty"`
// Annotations are additional mappings uninterpreted by Tiller,
// made available for inspection by other applications.
Annotations map[string]string `protobuf:"bytes,16,rep,name=annotations" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
Annotations map[string]string `protobuf:"bytes,16,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
// KubeVersion is a SemVer constraint specifying the version of Kubernetes required.
KubeVersion string `protobuf:"bytes,17,opt,name=kubeVersion" json:"kubeVersion,omitempty"`
KubeVersion string `protobuf:"bytes,17,opt,name=kubeVersion,proto3" json:"kubeVersion,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Metadata) Reset() { *m = Metadata{} }
func (m *Metadata) String() string { return proto.CompactTextString(m) }
func (*Metadata) ProtoMessage() {}
func (*Metadata) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{1} }
func (*Metadata) Descriptor() ([]byte, []int) {
return fileDescriptor_metadata_d6c714c73a051dcb, []int{1}
}
func (m *Metadata) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Metadata.Unmarshal(m, b)
}
func (m *Metadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Metadata.Marshal(b, m, deterministic)
}
func (dst *Metadata) XXX_Merge(src proto.Message) {
xxx_messageInfo_Metadata.Merge(dst, src)
}
func (m *Metadata) XXX_Size() int {
return xxx_messageInfo_Metadata.Size(m)
}
func (m *Metadata) XXX_DiscardUnknown() {
xxx_messageInfo_Metadata.DiscardUnknown(m)
}
var xxx_messageInfo_Metadata proto.InternalMessageInfo
func (m *Metadata) GetName() string {
if m != nil {
@ -238,12 +290,13 @@ func (m *Metadata) GetKubeVersion() string {
func init() {
proto.RegisterType((*Maintainer)(nil), "hapi.chart.Maintainer")
proto.RegisterType((*Metadata)(nil), "hapi.chart.Metadata")
proto.RegisterMapType((map[string]string)(nil), "hapi.chart.Metadata.AnnotationsEntry")
proto.RegisterEnum("hapi.chart.Metadata_Engine", Metadata_Engine_name, Metadata_Engine_value)
}
func init() { proto.RegisterFile("hapi/chart/metadata.proto", fileDescriptor2) }
func init() { proto.RegisterFile("hapi/chart/metadata.proto", fileDescriptor_metadata_d6c714c73a051dcb) }
var fileDescriptor2 = []byte{
var fileDescriptor_metadata_d6c714c73a051dcb = []byte{
// 435 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x52, 0x5d, 0x6b, 0xd4, 0x40,
0x14, 0x35, 0xcd, 0x66, 0x77, 0x73, 0x63, 0x35, 0x0e, 0x52, 0xc6, 0x22, 0x12, 0x16, 0x85, 0x7d,

@ -12,21 +12,49 @@ var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
// Template represents a template as a name/value pair.
//
// By convention, name is a relative path within the scope of the chart's
// base directory.
type Template struct {
// Name is the path-like name of the template.
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
// Data is the template as byte data.
Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Template) Reset() { *m = Template{} }
func (m *Template) String() string { return proto.CompactTextString(m) }
func (*Template) ProtoMessage() {}
func (*Template) Descriptor() ([]byte, []int) { return fileDescriptor3, []int{0} }
func (*Template) Descriptor() ([]byte, []int) {
return fileDescriptor_template_051845a7e9227d35, []int{0}
}
func (m *Template) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Template.Unmarshal(m, b)
}
func (m *Template) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Template.Marshal(b, m, deterministic)
}
func (dst *Template) XXX_Merge(src proto.Message) {
xxx_messageInfo_Template.Merge(dst, src)
}
func (m *Template) XXX_Size() int {
return xxx_messageInfo_Template.Size(m)
}
func (m *Template) XXX_DiscardUnknown() {
xxx_messageInfo_Template.DiscardUnknown(m)
}
var xxx_messageInfo_Template proto.InternalMessageInfo
func (m *Template) GetName() string {
if m != nil {
@ -46,9 +74,9 @@ func init() {
proto.RegisterType((*Template)(nil), "hapi.chart.Template")
}
func init() { proto.RegisterFile("hapi/chart/template.proto", fileDescriptor3) }
func init() { proto.RegisterFile("hapi/chart/template.proto", fileDescriptor_template_051845a7e9227d35) }
var fileDescriptor3 = []byte{
var fileDescriptor_template_051845a7e9227d35 = []byte{
// 107 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0xcc, 0x48, 0x2c, 0xc8,
0xd4, 0x4f, 0xce, 0x48, 0x2c, 0x2a, 0xd1, 0x2f, 0x49, 0xcd, 0x2d, 0xc8, 0x49, 0x2c, 0x49, 0xd5,

@ -1,31 +1,12 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: hapi/release/hook.proto
/*
Package release is a generated protocol buffer package.
It is generated from these files:
hapi/release/hook.proto
hapi/release/info.proto
hapi/release/release.proto
hapi/release/status.proto
hapi/release/test_run.proto
hapi/release/test_suite.proto
It has these top-level messages:
Hook
Info
Release
Status
TestRun
TestSuite
*/
package release
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import google_protobuf "github.com/golang/protobuf/ptypes/timestamp"
import timestamp "github.com/golang/protobuf/ptypes/timestamp"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
@ -87,7 +68,9 @@ var Hook_Event_value = map[string]int32{
func (x Hook_Event) String() string {
return proto.EnumName(Hook_Event_name, int32(x))
}
func (Hook_Event) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 0} }
func (Hook_Event) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_hook_8076b1a80af16030, []int{0, 0}
}
type Hook_DeletePolicy int32
@ -111,31 +94,55 @@ var Hook_DeletePolicy_value = map[string]int32{
func (x Hook_DeletePolicy) String() string {
return proto.EnumName(Hook_DeletePolicy_name, int32(x))
}
func (Hook_DeletePolicy) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 1} }
func (Hook_DeletePolicy) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_hook_8076b1a80af16030, []int{0, 1}
}
// Hook defines a hook object.
type Hook struct {
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
// Kind is the Kubernetes kind.
Kind string `protobuf:"bytes,2,opt,name=kind" json:"kind,omitempty"`
Kind string `protobuf:"bytes,2,opt,name=kind,proto3" json:"kind,omitempty"`
// Path is the chart-relative path to the template.
Path string `protobuf:"bytes,3,opt,name=path" json:"path,omitempty"`
Path string `protobuf:"bytes,3,opt,name=path,proto3" json:"path,omitempty"`
// Manifest is the manifest contents.
Manifest string `protobuf:"bytes,4,opt,name=manifest" json:"manifest,omitempty"`
Manifest string `protobuf:"bytes,4,opt,name=manifest,proto3" json:"manifest,omitempty"`
// Events are the events that this hook fires on.
Events []Hook_Event `protobuf:"varint,5,rep,packed,name=events,enum=hapi.release.Hook_Event" json:"events,omitempty"`
Events []Hook_Event `protobuf:"varint,5,rep,packed,name=events,proto3,enum=hapi.release.Hook_Event" json:"events,omitempty"`
// LastRun indicates the date/time this was last run.
LastRun *google_protobuf.Timestamp `protobuf:"bytes,6,opt,name=last_run,json=lastRun" json:"last_run,omitempty"`
LastRun *timestamp.Timestamp `protobuf:"bytes,6,opt,name=last_run,json=lastRun,proto3" json:"last_run,omitempty"`
// Weight indicates the sort order for execution among similar Hook type
Weight int32 `protobuf:"varint,7,opt,name=weight" json:"weight,omitempty"`
Weight int32 `protobuf:"varint,7,opt,name=weight,proto3" json:"weight,omitempty"`
// DeletePolicies are the policies that indicate when to delete the hook
DeletePolicies []Hook_DeletePolicy `protobuf:"varint,8,rep,packed,name=delete_policies,json=deletePolicies,enum=hapi.release.Hook_DeletePolicy" json:"delete_policies,omitempty"`
DeletePolicies []Hook_DeletePolicy `protobuf:"varint,8,rep,packed,name=delete_policies,json=deletePolicies,proto3,enum=hapi.release.Hook_DeletePolicy" json:"delete_policies,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Hook) Reset() { *m = Hook{} }
func (m *Hook) String() string { return proto.CompactTextString(m) }
func (*Hook) ProtoMessage() {}
func (*Hook) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (*Hook) Descriptor() ([]byte, []int) {
return fileDescriptor_hook_8076b1a80af16030, []int{0}
}
func (m *Hook) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Hook.Unmarshal(m, b)
}
func (m *Hook) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Hook.Marshal(b, m, deterministic)
}
func (dst *Hook) XXX_Merge(src proto.Message) {
xxx_messageInfo_Hook.Merge(dst, src)
}
func (m *Hook) XXX_Size() int {
return xxx_messageInfo_Hook.Size(m)
}
func (m *Hook) XXX_DiscardUnknown() {
xxx_messageInfo_Hook.DiscardUnknown(m)
}
var xxx_messageInfo_Hook proto.InternalMessageInfo
func (m *Hook) GetName() string {
if m != nil {
@ -172,7 +179,7 @@ func (m *Hook) GetEvents() []Hook_Event {
return nil
}
func (m *Hook) GetLastRun() *google_protobuf.Timestamp {
func (m *Hook) GetLastRun() *timestamp.Timestamp {
if m != nil {
return m.LastRun
}
@ -199,9 +206,9 @@ func init() {
proto.RegisterEnum("hapi.release.Hook_DeletePolicy", Hook_DeletePolicy_name, Hook_DeletePolicy_value)
}
func init() { proto.RegisterFile("hapi/release/hook.proto", fileDescriptor0) }
func init() { proto.RegisterFile("hapi/release/hook.proto", fileDescriptor_hook_8076b1a80af16030) }
var fileDescriptor0 = []byte{
var fileDescriptor_hook_8076b1a80af16030 = []byte{
// 453 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x91, 0x51, 0x8f, 0x9a, 0x40,
0x10, 0x80, 0x8f, 0x53, 0x41, 0x47, 0xcf, 0xdb, 0x6e, 0x9a, 0x76, 0xe3, 0xcb, 0x19, 0x9f, 0x7c,

@ -6,28 +6,56 @@ package release
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import google_protobuf "github.com/golang/protobuf/ptypes/timestamp"
import timestamp "github.com/golang/protobuf/ptypes/timestamp"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
// Info describes release information.
type Info struct {
Status *Status `protobuf:"bytes,1,opt,name=status" json:"status,omitempty"`
FirstDeployed *google_protobuf.Timestamp `protobuf:"bytes,2,opt,name=first_deployed,json=firstDeployed" json:"first_deployed,omitempty"`
LastDeployed *google_protobuf.Timestamp `protobuf:"bytes,3,opt,name=last_deployed,json=lastDeployed" json:"last_deployed,omitempty"`
Status *Status `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"`
FirstDeployed *timestamp.Timestamp `protobuf:"bytes,2,opt,name=first_deployed,json=firstDeployed,proto3" json:"first_deployed,omitempty"`
LastDeployed *timestamp.Timestamp `protobuf:"bytes,3,opt,name=last_deployed,json=lastDeployed,proto3" json:"last_deployed,omitempty"`
// Deleted tracks when this object was deleted.
Deleted *google_protobuf.Timestamp `protobuf:"bytes,4,opt,name=deleted" json:"deleted,omitempty"`
Deleted *timestamp.Timestamp `protobuf:"bytes,4,opt,name=deleted,proto3" json:"deleted,omitempty"`
// Description is human-friendly "log entry" about this release.
Description string `protobuf:"bytes,5,opt,name=Description" json:"Description,omitempty"`
Description string `protobuf:"bytes,5,opt,name=Description,proto3" json:"Description,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Info) Reset() { *m = Info{} }
func (m *Info) String() string { return proto.CompactTextString(m) }
func (*Info) ProtoMessage() {}
func (*Info) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{0} }
func (*Info) Descriptor() ([]byte, []int) {
return fileDescriptor_info_1c62b71ed76c67c1, []int{0}
}
func (m *Info) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Info.Unmarshal(m, b)
}
func (m *Info) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Info.Marshal(b, m, deterministic)
}
func (dst *Info) XXX_Merge(src proto.Message) {
xxx_messageInfo_Info.Merge(dst, src)
}
func (m *Info) XXX_Size() int {
return xxx_messageInfo_Info.Size(m)
}
func (m *Info) XXX_DiscardUnknown() {
xxx_messageInfo_Info.DiscardUnknown(m)
}
var xxx_messageInfo_Info proto.InternalMessageInfo
func (m *Info) GetStatus() *Status {
if m != nil {
@ -36,21 +64,21 @@ func (m *Info) GetStatus() *Status {
return nil
}
func (m *Info) GetFirstDeployed() *google_protobuf.Timestamp {
func (m *Info) GetFirstDeployed() *timestamp.Timestamp {
if m != nil {
return m.FirstDeployed
}
return nil
}
func (m *Info) GetLastDeployed() *google_protobuf.Timestamp {
func (m *Info) GetLastDeployed() *timestamp.Timestamp {
if m != nil {
return m.LastDeployed
}
return nil
}
func (m *Info) GetDeleted() *google_protobuf.Timestamp {
func (m *Info) GetDeleted() *timestamp.Timestamp {
if m != nil {
return m.Deleted
}
@ -68,9 +96,9 @@ func init() {
proto.RegisterType((*Info)(nil), "hapi.release.Info")
}
func init() { proto.RegisterFile("hapi/release/info.proto", fileDescriptor1) }
func init() { proto.RegisterFile("hapi/release/info.proto", fileDescriptor_info_1c62b71ed76c67c1) }
var fileDescriptor1 = []byte{
var fileDescriptor_info_1c62b71ed76c67c1 = []byte{
// 235 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x8f, 0x31, 0x4f, 0xc3, 0x30,
0x10, 0x85, 0x95, 0x52, 0x5a, 0xd5, 0x6d, 0x19, 0x2c, 0x24, 0x42, 0x16, 0x22, 0xa6, 0x0e, 0xc8,

@ -6,40 +6,67 @@ package release
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import hapi_chart "k8s.io/helm/pkg/proto/hapi/chart"
import hapi_chart3 "k8s.io/helm/pkg/proto/hapi/chart"
import chart "k8s.io/helm/pkg/proto/hapi/chart"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
// Release describes a deployment of a chart, together with the chart
// and the variables used to deploy that chart.
type Release struct {
// Name is the name of the release
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
// Info provides information about a release
Info *Info `protobuf:"bytes,2,opt,name=info" json:"info,omitempty"`
Info *Info `protobuf:"bytes,2,opt,name=info,proto3" json:"info,omitempty"`
// Chart is the chart that was released.
Chart *hapi_chart3.Chart `protobuf:"bytes,3,opt,name=chart" json:"chart,omitempty"`
Chart *chart.Chart `protobuf:"bytes,3,opt,name=chart,proto3" json:"chart,omitempty"`
// Config is the set of extra Values added to the chart.
// These values override the default values inside of the chart.
Config *hapi_chart.Config `protobuf:"bytes,4,opt,name=config" json:"config,omitempty"`
Config *chart.Config `protobuf:"bytes,4,opt,name=config,proto3" json:"config,omitempty"`
// Manifest is the string representation of the rendered template.
Manifest string `protobuf:"bytes,5,opt,name=manifest" json:"manifest,omitempty"`
Manifest string `protobuf:"bytes,5,opt,name=manifest,proto3" json:"manifest,omitempty"`
// Hooks are all of the hooks declared for this release.
Hooks []*Hook `protobuf:"bytes,6,rep,name=hooks" json:"hooks,omitempty"`
Hooks []*Hook `protobuf:"bytes,6,rep,name=hooks,proto3" json:"hooks,omitempty"`
// Version is an int32 which represents the version of the release.
Version int32 `protobuf:"varint,7,opt,name=version" json:"version,omitempty"`
Version int32 `protobuf:"varint,7,opt,name=version,proto3" json:"version,omitempty"`
// Namespace is the kubernetes namespace of the release.
Namespace string `protobuf:"bytes,8,opt,name=namespace" json:"namespace,omitempty"`
Namespace string `protobuf:"bytes,8,opt,name=namespace,proto3" json:"namespace,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Release) Reset() { *m = Release{} }
func (m *Release) String() string { return proto.CompactTextString(m) }
func (*Release) ProtoMessage() {}
func (*Release) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{0} }
func (*Release) Descriptor() ([]byte, []int) {
return fileDescriptor_release_4bea5d16ba219619, []int{0}
}
func (m *Release) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Release.Unmarshal(m, b)
}
func (m *Release) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Release.Marshal(b, m, deterministic)
}
func (dst *Release) XXX_Merge(src proto.Message) {
xxx_messageInfo_Release.Merge(dst, src)
}
func (m *Release) XXX_Size() int {
return xxx_messageInfo_Release.Size(m)
}
func (m *Release) XXX_DiscardUnknown() {
xxx_messageInfo_Release.DiscardUnknown(m)
}
var xxx_messageInfo_Release proto.InternalMessageInfo
func (m *Release) GetName() string {
if m != nil {
@ -55,14 +82,14 @@ func (m *Release) GetInfo() *Info {
return nil
}
func (m *Release) GetChart() *hapi_chart3.Chart {
func (m *Release) GetChart() *chart.Chart {
if m != nil {
return m.Chart
}
return nil
}
func (m *Release) GetConfig() *hapi_chart.Config {
func (m *Release) GetConfig() *chart.Config {
if m != nil {
return m.Config
}
@ -101,9 +128,9 @@ func init() {
proto.RegisterType((*Release)(nil), "hapi.release.Release")
}
func init() { proto.RegisterFile("hapi/release/release.proto", fileDescriptor2) }
func init() { proto.RegisterFile("hapi/release/release.proto", fileDescriptor_release_4bea5d16ba219619) }
var fileDescriptor2 = []byte{
var fileDescriptor_release_4bea5d16ba219619 = []byte{
// 256 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x90, 0xbf, 0x4e, 0xc3, 0x40,
0x0c, 0xc6, 0x95, 0x36, 0x7f, 0x1a, 0xc3, 0x82, 0x07, 0xb0, 0x22, 0x86, 0x88, 0x01, 0x22, 0x86,

@ -13,6 +13,12 @@ var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type Status_Code int32
const (
@ -62,23 +68,47 @@ var Status_Code_value = map[string]int32{
func (x Status_Code) String() string {
return proto.EnumName(Status_Code_name, int32(x))
}
func (Status_Code) EnumDescriptor() ([]byte, []int) { return fileDescriptor3, []int{0, 0} }
func (Status_Code) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_status_933517e5a50981ed, []int{0, 0}
}
// Status defines the status of a release.
type Status struct {
Code Status_Code `protobuf:"varint,1,opt,name=code,enum=hapi.release.Status_Code" json:"code,omitempty"`
Code Status_Code `protobuf:"varint,1,opt,name=code,proto3,enum=hapi.release.Status_Code" json:"code,omitempty"`
// Cluster resources as kubectl would print them.
Resources string `protobuf:"bytes,3,opt,name=resources" json:"resources,omitempty"`
Resources string `protobuf:"bytes,3,opt,name=resources,proto3" json:"resources,omitempty"`
// Contains the rendered templates/NOTES.txt if available
Notes string `protobuf:"bytes,4,opt,name=notes" json:"notes,omitempty"`
Notes string `protobuf:"bytes,4,opt,name=notes,proto3" json:"notes,omitempty"`
// LastTestSuiteRun provides results on the last test run on a release
LastTestSuiteRun *TestSuite `protobuf:"bytes,5,opt,name=last_test_suite_run,json=lastTestSuiteRun" json:"last_test_suite_run,omitempty"`
LastTestSuiteRun *TestSuite `protobuf:"bytes,5,opt,name=last_test_suite_run,json=lastTestSuiteRun,proto3" json:"last_test_suite_run,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Status) Reset() { *m = Status{} }
func (m *Status) String() string { return proto.CompactTextString(m) }
func (*Status) ProtoMessage() {}
func (*Status) Descriptor() ([]byte, []int) { return fileDescriptor3, []int{0} }
func (*Status) Descriptor() ([]byte, []int) {
return fileDescriptor_status_933517e5a50981ed, []int{0}
}
func (m *Status) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Status.Unmarshal(m, b)
}
func (m *Status) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Status.Marshal(b, m, deterministic)
}
func (dst *Status) XXX_Merge(src proto.Message) {
xxx_messageInfo_Status.Merge(dst, src)
}
func (m *Status) XXX_Size() int {
return xxx_messageInfo_Status.Size(m)
}
func (m *Status) XXX_DiscardUnknown() {
xxx_messageInfo_Status.DiscardUnknown(m)
}
var xxx_messageInfo_Status proto.InternalMessageInfo
func (m *Status) GetCode() Status_Code {
if m != nil {
@ -113,9 +143,9 @@ func init() {
proto.RegisterEnum("hapi.release.Status_Code", Status_Code_name, Status_Code_value)
}
func init() { proto.RegisterFile("hapi/release/status.proto", fileDescriptor3) }
func init() { proto.RegisterFile("hapi/release/status.proto", fileDescriptor_status_933517e5a50981ed) }
var fileDescriptor3 = []byte{
var fileDescriptor_status_933517e5a50981ed = []byte{
// 333 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x90, 0xd1, 0x6e, 0xa2, 0x40,
0x14, 0x86, 0x17, 0x45, 0xd4, 0xa3, 0x71, 0x27, 0xa3, 0xc9, 0xa2, 0xd9, 0x4d, 0x8c, 0x57, 0xde,

@ -6,13 +6,19 @@ package release
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import google_protobuf "github.com/golang/protobuf/ptypes/timestamp"
import timestamp "github.com/golang/protobuf/ptypes/timestamp"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type TestRun_Status int32
const (
@ -38,20 +44,44 @@ var TestRun_Status_value = map[string]int32{
func (x TestRun_Status) String() string {
return proto.EnumName(TestRun_Status_name, int32(x))
}
func (TestRun_Status) EnumDescriptor() ([]byte, []int) { return fileDescriptor4, []int{0, 0} }
func (TestRun_Status) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_test_run_31b133e40c63664e, []int{0, 0}
}
type TestRun struct {
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
Status TestRun_Status `protobuf:"varint,2,opt,name=status,enum=hapi.release.TestRun_Status" json:"status,omitempty"`
Info string `protobuf:"bytes,3,opt,name=info" json:"info,omitempty"`
StartedAt *google_protobuf.Timestamp `protobuf:"bytes,4,opt,name=started_at,json=startedAt" json:"started_at,omitempty"`
CompletedAt *google_protobuf.Timestamp `protobuf:"bytes,5,opt,name=completed_at,json=completedAt" json:"completed_at,omitempty"`
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Status TestRun_Status `protobuf:"varint,2,opt,name=status,proto3,enum=hapi.release.TestRun_Status" json:"status,omitempty"`
Info string `protobuf:"bytes,3,opt,name=info,proto3" json:"info,omitempty"`
StartedAt *timestamp.Timestamp `protobuf:"bytes,4,opt,name=started_at,json=startedAt,proto3" json:"started_at,omitempty"`
CompletedAt *timestamp.Timestamp `protobuf:"bytes,5,opt,name=completed_at,json=completedAt,proto3" json:"completed_at,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *TestRun) Reset() { *m = TestRun{} }
func (m *TestRun) String() string { return proto.CompactTextString(m) }
func (*TestRun) ProtoMessage() {}
func (*TestRun) Descriptor() ([]byte, []int) { return fileDescriptor4, []int{0} }
func (*TestRun) Descriptor() ([]byte, []int) {
return fileDescriptor_test_run_31b133e40c63664e, []int{0}
}
func (m *TestRun) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_TestRun.Unmarshal(m, b)
}
func (m *TestRun) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_TestRun.Marshal(b, m, deterministic)
}
func (dst *TestRun) XXX_Merge(src proto.Message) {
xxx_messageInfo_TestRun.Merge(dst, src)
}
func (m *TestRun) XXX_Size() int {
return xxx_messageInfo_TestRun.Size(m)
}
func (m *TestRun) XXX_DiscardUnknown() {
xxx_messageInfo_TestRun.DiscardUnknown(m)
}
var xxx_messageInfo_TestRun proto.InternalMessageInfo
func (m *TestRun) GetName() string {
if m != nil {
@ -74,14 +104,14 @@ func (m *TestRun) GetInfo() string {
return ""
}
func (m *TestRun) GetStartedAt() *google_protobuf.Timestamp {
func (m *TestRun) GetStartedAt() *timestamp.Timestamp {
if m != nil {
return m.StartedAt
}
return nil
}
func (m *TestRun) GetCompletedAt() *google_protobuf.Timestamp {
func (m *TestRun) GetCompletedAt() *timestamp.Timestamp {
if m != nil {
return m.CompletedAt
}
@ -93,9 +123,11 @@ func init() {
proto.RegisterEnum("hapi.release.TestRun_Status", TestRun_Status_name, TestRun_Status_value)
}
func init() { proto.RegisterFile("hapi/release/test_run.proto", fileDescriptor4) }
func init() {
proto.RegisterFile("hapi/release/test_run.proto", fileDescriptor_test_run_31b133e40c63664e)
}
var fileDescriptor4 = []byte{
var fileDescriptor_test_run_31b133e40c63664e = []byte{
// 274 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x8f, 0xc1, 0x4b, 0xfb, 0x30,
0x1c, 0xc5, 0x7f, 0xe9, 0xf6, 0x6b, 0x69, 0x3a, 0xa4, 0xe4, 0x54, 0xa6, 0x60, 0xd9, 0xa9, 0xa7,

@ -6,36 +6,64 @@ package release
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import google_protobuf "github.com/golang/protobuf/ptypes/timestamp"
import timestamp "github.com/golang/protobuf/ptypes/timestamp"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
// TestSuite comprises of the last run of the pre-defined test suite of a release version
type TestSuite struct {
// StartedAt indicates the date/time this test suite was kicked off
StartedAt *google_protobuf.Timestamp `protobuf:"bytes,1,opt,name=started_at,json=startedAt" json:"started_at,omitempty"`
StartedAt *timestamp.Timestamp `protobuf:"bytes,1,opt,name=started_at,json=startedAt,proto3" json:"started_at,omitempty"`
// CompletedAt indicates the date/time this test suite was completed
CompletedAt *google_protobuf.Timestamp `protobuf:"bytes,2,opt,name=completed_at,json=completedAt" json:"completed_at,omitempty"`
CompletedAt *timestamp.Timestamp `protobuf:"bytes,2,opt,name=completed_at,json=completedAt,proto3" json:"completed_at,omitempty"`
// Results are the results of each segment of the test
Results []*TestRun `protobuf:"bytes,3,rep,name=results" json:"results,omitempty"`
Results []*TestRun `protobuf:"bytes,3,rep,name=results,proto3" json:"results,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *TestSuite) Reset() { *m = TestSuite{} }
func (m *TestSuite) String() string { return proto.CompactTextString(m) }
func (*TestSuite) ProtoMessage() {}
func (*TestSuite) Descriptor() ([]byte, []int) { return fileDescriptor5, []int{0} }
func (*TestSuite) Descriptor() ([]byte, []int) {
return fileDescriptor_test_suite_06a0016f2c6417b8, []int{0}
}
func (m *TestSuite) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_TestSuite.Unmarshal(m, b)
}
func (m *TestSuite) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_TestSuite.Marshal(b, m, deterministic)
}
func (dst *TestSuite) XXX_Merge(src proto.Message) {
xxx_messageInfo_TestSuite.Merge(dst, src)
}
func (m *TestSuite) XXX_Size() int {
return xxx_messageInfo_TestSuite.Size(m)
}
func (m *TestSuite) XXX_DiscardUnknown() {
xxx_messageInfo_TestSuite.DiscardUnknown(m)
}
var xxx_messageInfo_TestSuite proto.InternalMessageInfo
func (m *TestSuite) GetStartedAt() *google_protobuf.Timestamp {
func (m *TestSuite) GetStartedAt() *timestamp.Timestamp {
if m != nil {
return m.StartedAt
}
return nil
}
func (m *TestSuite) GetCompletedAt() *google_protobuf.Timestamp {
func (m *TestSuite) GetCompletedAt() *timestamp.Timestamp {
if m != nil {
return m.CompletedAt
}
@ -53,9 +81,11 @@ func init() {
proto.RegisterType((*TestSuite)(nil), "hapi.release.TestSuite")
}
func init() { proto.RegisterFile("hapi/release/test_suite.proto", fileDescriptor5) }
func init() {
proto.RegisterFile("hapi/release/test_suite.proto", fileDescriptor_test_suite_06a0016f2c6417b8)
}
var fileDescriptor5 = []byte{
var fileDescriptor_test_suite_06a0016f2c6417b8 = []byte{
// 207 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x8f, 0xc1, 0x4a, 0x86, 0x40,
0x14, 0x85, 0x31, 0x21, 0x71, 0x74, 0x35, 0x10, 0x88, 0x11, 0x49, 0x2b, 0x57, 0x33, 0x60, 0xab,

@ -1,34 +1,12 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: hapi/rudder/rudder.proto
/*
Package rudder is a generated protocol buffer package.
It is generated from these files:
hapi/rudder/rudder.proto
It has these top-level messages:
Result
VersionReleaseRequest
VersionReleaseResponse
InstallReleaseRequest
InstallReleaseResponse
DeleteReleaseRequest
DeleteReleaseResponse
UpgradeReleaseRequest
UpgradeReleaseResponse
RollbackReleaseRequest
RollbackReleaseResponse
ReleaseStatusRequest
ReleaseStatusResponse
*/
package rudder
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import hapi_release3 "k8s.io/helm/pkg/proto/hapi/release"
import hapi_release5 "k8s.io/helm/pkg/proto/hapi/release"
import release "k8s.io/helm/pkg/proto/hapi/release"
import (
context "golang.org/x/net/context"
@ -75,17 +53,41 @@ var Result_Status_value = map[string]int32{
func (x Result_Status) String() string {
return proto.EnumName(Result_Status_name, int32(x))
}
func (Result_Status) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 0} }
func (Result_Status) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_rudder_dd8cdbe38a210d28, []int{0, 0}
}
type Result struct {
Info string `protobuf:"bytes,1,opt,name=info" json:"info,omitempty"`
Log []string `protobuf:"bytes,2,rep,name=log" json:"log,omitempty"`
Info string `protobuf:"bytes,1,opt,name=info,proto3" json:"info,omitempty"`
Log []string `protobuf:"bytes,2,rep,name=log,proto3" json:"log,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Result) Reset() { *m = Result{} }
func (m *Result) String() string { return proto.CompactTextString(m) }
func (*Result) ProtoMessage() {}
func (*Result) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (*Result) Descriptor() ([]byte, []int) {
return fileDescriptor_rudder_dd8cdbe38a210d28, []int{0}
}
func (m *Result) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Result.Unmarshal(m, b)
}
func (m *Result) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Result.Marshal(b, m, deterministic)
}
func (dst *Result) XXX_Merge(src proto.Message) {
xxx_messageInfo_Result.Merge(dst, src)
}
func (m *Result) XXX_Size() int {
return xxx_messageInfo_Result.Size(m)
}
func (m *Result) XXX_DiscardUnknown() {
xxx_messageInfo_Result.DiscardUnknown(m)
}
var xxx_messageInfo_Result proto.InternalMessageInfo
func (m *Result) GetInfo() string {
if m != nil {
@ -102,22 +104,66 @@ func (m *Result) GetLog() []string {
}
type VersionReleaseRequest struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *VersionReleaseRequest) Reset() { *m = VersionReleaseRequest{} }
func (m *VersionReleaseRequest) String() string { return proto.CompactTextString(m) }
func (*VersionReleaseRequest) ProtoMessage() {}
func (*VersionReleaseRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
func (*VersionReleaseRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rudder_dd8cdbe38a210d28, []int{1}
}
func (m *VersionReleaseRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_VersionReleaseRequest.Unmarshal(m, b)
}
func (m *VersionReleaseRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_VersionReleaseRequest.Marshal(b, m, deterministic)
}
func (dst *VersionReleaseRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_VersionReleaseRequest.Merge(dst, src)
}
func (m *VersionReleaseRequest) XXX_Size() int {
return xxx_messageInfo_VersionReleaseRequest.Size(m)
}
func (m *VersionReleaseRequest) XXX_DiscardUnknown() {
xxx_messageInfo_VersionReleaseRequest.DiscardUnknown(m)
}
var xxx_messageInfo_VersionReleaseRequest proto.InternalMessageInfo
type VersionReleaseResponse struct {
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
Version string `protobuf:"bytes,2,opt,name=version" json:"version,omitempty"`
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *VersionReleaseResponse) Reset() { *m = VersionReleaseResponse{} }
func (m *VersionReleaseResponse) String() string { return proto.CompactTextString(m) }
func (*VersionReleaseResponse) ProtoMessage() {}
func (*VersionReleaseResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
func (*VersionReleaseResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rudder_dd8cdbe38a210d28, []int{2}
}
func (m *VersionReleaseResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_VersionReleaseResponse.Unmarshal(m, b)
}
func (m *VersionReleaseResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_VersionReleaseResponse.Marshal(b, m, deterministic)
}
func (dst *VersionReleaseResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_VersionReleaseResponse.Merge(dst, src)
}
func (m *VersionReleaseResponse) XXX_Size() int {
return xxx_messageInfo_VersionReleaseResponse.Size(m)
}
func (m *VersionReleaseResponse) XXX_DiscardUnknown() {
xxx_messageInfo_VersionReleaseResponse.DiscardUnknown(m)
}
var xxx_messageInfo_VersionReleaseResponse proto.InternalMessageInfo
func (m *VersionReleaseResponse) GetName() string {
if m != nil {
@ -134,15 +180,37 @@ func (m *VersionReleaseResponse) GetVersion() string {
}
type InstallReleaseRequest struct {
Release *hapi_release5.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"`
Release *release.Release `protobuf:"bytes,1,opt,name=release,proto3" json:"release,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *InstallReleaseRequest) Reset() { *m = InstallReleaseRequest{} }
func (m *InstallReleaseRequest) String() string { return proto.CompactTextString(m) }
func (*InstallReleaseRequest) ProtoMessage() {}
func (*InstallReleaseRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
func (*InstallReleaseRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rudder_dd8cdbe38a210d28, []int{3}
}
func (m *InstallReleaseRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_InstallReleaseRequest.Unmarshal(m, b)
}
func (m *InstallReleaseRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_InstallReleaseRequest.Marshal(b, m, deterministic)
}
func (dst *InstallReleaseRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_InstallReleaseRequest.Merge(dst, src)
}
func (m *InstallReleaseRequest) XXX_Size() int {
return xxx_messageInfo_InstallReleaseRequest.Size(m)
}
func (m *InstallReleaseRequest) XXX_DiscardUnknown() {
xxx_messageInfo_InstallReleaseRequest.DiscardUnknown(m)
}
var xxx_messageInfo_InstallReleaseRequest proto.InternalMessageInfo
func (m *InstallReleaseRequest) GetRelease() *hapi_release5.Release {
func (m *InstallReleaseRequest) GetRelease() *release.Release {
if m != nil {
return m.Release
}
@ -150,16 +218,38 @@ func (m *InstallReleaseRequest) GetRelease() *hapi_release5.Release {
}
type InstallReleaseResponse struct {
Release *hapi_release5.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"`
Result *Result `protobuf:"bytes,2,opt,name=result" json:"result,omitempty"`
Release *release.Release `protobuf:"bytes,1,opt,name=release,proto3" json:"release,omitempty"`
Result *Result `protobuf:"bytes,2,opt,name=result,proto3" json:"result,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *InstallReleaseResponse) Reset() { *m = InstallReleaseResponse{} }
func (m *InstallReleaseResponse) String() string { return proto.CompactTextString(m) }
func (*InstallReleaseResponse) ProtoMessage() {}
func (*InstallReleaseResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
func (*InstallReleaseResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rudder_dd8cdbe38a210d28, []int{4}
}
func (m *InstallReleaseResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_InstallReleaseResponse.Unmarshal(m, b)
}
func (m *InstallReleaseResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_InstallReleaseResponse.Marshal(b, m, deterministic)
}
func (dst *InstallReleaseResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_InstallReleaseResponse.Merge(dst, src)
}
func (m *InstallReleaseResponse) XXX_Size() int {
return xxx_messageInfo_InstallReleaseResponse.Size(m)
}
func (m *InstallReleaseResponse) XXX_DiscardUnknown() {
xxx_messageInfo_InstallReleaseResponse.DiscardUnknown(m)
}
var xxx_messageInfo_InstallReleaseResponse proto.InternalMessageInfo
func (m *InstallReleaseResponse) GetRelease() *hapi_release5.Release {
func (m *InstallReleaseResponse) GetRelease() *release.Release {
if m != nil {
return m.Release
}
@ -174,15 +264,37 @@ func (m *InstallReleaseResponse) GetResult() *Result {
}
type DeleteReleaseRequest struct {
Release *hapi_release5.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"`
Release *release.Release `protobuf:"bytes,1,opt,name=release,proto3" json:"release,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *DeleteReleaseRequest) Reset() { *m = DeleteReleaseRequest{} }
func (m *DeleteReleaseRequest) String() string { return proto.CompactTextString(m) }
func (*DeleteReleaseRequest) ProtoMessage() {}
func (*DeleteReleaseRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} }
func (*DeleteReleaseRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rudder_dd8cdbe38a210d28, []int{5}
}
func (m *DeleteReleaseRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_DeleteReleaseRequest.Unmarshal(m, b)
}
func (m *DeleteReleaseRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_DeleteReleaseRequest.Marshal(b, m, deterministic)
}
func (dst *DeleteReleaseRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_DeleteReleaseRequest.Merge(dst, src)
}
func (m *DeleteReleaseRequest) XXX_Size() int {
return xxx_messageInfo_DeleteReleaseRequest.Size(m)
}
func (m *DeleteReleaseRequest) XXX_DiscardUnknown() {
xxx_messageInfo_DeleteReleaseRequest.DiscardUnknown(m)
}
func (m *DeleteReleaseRequest) GetRelease() *hapi_release5.Release {
var xxx_messageInfo_DeleteReleaseRequest proto.InternalMessageInfo
func (m *DeleteReleaseRequest) GetRelease() *release.Release {
if m != nil {
return m.Release
}
@ -190,16 +302,38 @@ func (m *DeleteReleaseRequest) GetRelease() *hapi_release5.Release {
}
type DeleteReleaseResponse struct {
Release *hapi_release5.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"`
Result *Result `protobuf:"bytes,2,opt,name=result" json:"result,omitempty"`
Release *release.Release `protobuf:"bytes,1,opt,name=release,proto3" json:"release,omitempty"`
Result *Result `protobuf:"bytes,2,opt,name=result,proto3" json:"result,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *DeleteReleaseResponse) Reset() { *m = DeleteReleaseResponse{} }
func (m *DeleteReleaseResponse) String() string { return proto.CompactTextString(m) }
func (*DeleteReleaseResponse) ProtoMessage() {}
func (*DeleteReleaseResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} }
func (*DeleteReleaseResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rudder_dd8cdbe38a210d28, []int{6}
}
func (m *DeleteReleaseResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_DeleteReleaseResponse.Unmarshal(m, b)
}
func (m *DeleteReleaseResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_DeleteReleaseResponse.Marshal(b, m, deterministic)
}
func (dst *DeleteReleaseResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_DeleteReleaseResponse.Merge(dst, src)
}
func (m *DeleteReleaseResponse) XXX_Size() int {
return xxx_messageInfo_DeleteReleaseResponse.Size(m)
}
func (m *DeleteReleaseResponse) XXX_DiscardUnknown() {
xxx_messageInfo_DeleteReleaseResponse.DiscardUnknown(m)
}
var xxx_messageInfo_DeleteReleaseResponse proto.InternalMessageInfo
func (m *DeleteReleaseResponse) GetRelease() *hapi_release5.Release {
func (m *DeleteReleaseResponse) GetRelease() *release.Release {
if m != nil {
return m.Release
}
@ -214,28 +348,50 @@ func (m *DeleteReleaseResponse) GetResult() *Result {
}
type UpgradeReleaseRequest struct {
Current *hapi_release5.Release `protobuf:"bytes,1,opt,name=current" json:"current,omitempty"`
Target *hapi_release5.Release `protobuf:"bytes,2,opt,name=target" json:"target,omitempty"`
Timeout int64 `protobuf:"varint,3,opt,name=Timeout" json:"Timeout,omitempty"`
Wait bool `protobuf:"varint,4,opt,name=Wait" json:"Wait,omitempty"`
Recreate bool `protobuf:"varint,5,opt,name=Recreate" json:"Recreate,omitempty"`
Force bool `protobuf:"varint,6,opt,name=Force" json:"Force,omitempty"`
CleanupOnFail bool `protobuf:"varint,7,opt,name=CleanupOnFail" json:"CleanupOnFail,omitempty"`
Current *release.Release `protobuf:"bytes,1,opt,name=current,proto3" json:"current,omitempty"`
Target *release.Release `protobuf:"bytes,2,opt,name=target,proto3" json:"target,omitempty"`
Timeout int64 `protobuf:"varint,3,opt,name=Timeout,proto3" json:"Timeout,omitempty"`
Wait bool `protobuf:"varint,4,opt,name=Wait,proto3" json:"Wait,omitempty"`
Recreate bool `protobuf:"varint,5,opt,name=Recreate,proto3" json:"Recreate,omitempty"`
Force bool `protobuf:"varint,6,opt,name=Force,proto3" json:"Force,omitempty"`
CleanupOnFail bool `protobuf:"varint,7,opt,name=CleanupOnFail,proto3" json:"CleanupOnFail,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *UpgradeReleaseRequest) Reset() { *m = UpgradeReleaseRequest{} }
func (m *UpgradeReleaseRequest) String() string { return proto.CompactTextString(m) }
func (*UpgradeReleaseRequest) ProtoMessage() {}
func (*UpgradeReleaseRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
func (*UpgradeReleaseRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rudder_dd8cdbe38a210d28, []int{7}
}
func (m *UpgradeReleaseRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_UpgradeReleaseRequest.Unmarshal(m, b)
}
func (m *UpgradeReleaseRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_UpgradeReleaseRequest.Marshal(b, m, deterministic)
}
func (dst *UpgradeReleaseRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_UpgradeReleaseRequest.Merge(dst, src)
}
func (m *UpgradeReleaseRequest) XXX_Size() int {
return xxx_messageInfo_UpgradeReleaseRequest.Size(m)
}
func (m *UpgradeReleaseRequest) XXX_DiscardUnknown() {
xxx_messageInfo_UpgradeReleaseRequest.DiscardUnknown(m)
}
func (m *UpgradeReleaseRequest) GetCurrent() *hapi_release5.Release {
var xxx_messageInfo_UpgradeReleaseRequest proto.InternalMessageInfo
func (m *UpgradeReleaseRequest) GetCurrent() *release.Release {
if m != nil {
return m.Current
}
return nil
}
func (m *UpgradeReleaseRequest) GetTarget() *hapi_release5.Release {
func (m *UpgradeReleaseRequest) GetTarget() *release.Release {
if m != nil {
return m.Target
}
@ -278,16 +434,38 @@ func (m *UpgradeReleaseRequest) GetCleanupOnFail() bool {
}
type UpgradeReleaseResponse struct {
Release *hapi_release5.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"`
Result *Result `protobuf:"bytes,2,opt,name=result" json:"result,omitempty"`
Release *release.Release `protobuf:"bytes,1,opt,name=release,proto3" json:"release,omitempty"`
Result *Result `protobuf:"bytes,2,opt,name=result,proto3" json:"result,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *UpgradeReleaseResponse) Reset() { *m = UpgradeReleaseResponse{} }
func (m *UpgradeReleaseResponse) String() string { return proto.CompactTextString(m) }
func (*UpgradeReleaseResponse) ProtoMessage() {}
func (*UpgradeReleaseResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} }
func (*UpgradeReleaseResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rudder_dd8cdbe38a210d28, []int{8}
}
func (m *UpgradeReleaseResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_UpgradeReleaseResponse.Unmarshal(m, b)
}
func (m *UpgradeReleaseResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_UpgradeReleaseResponse.Marshal(b, m, deterministic)
}
func (dst *UpgradeReleaseResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_UpgradeReleaseResponse.Merge(dst, src)
}
func (m *UpgradeReleaseResponse) XXX_Size() int {
return xxx_messageInfo_UpgradeReleaseResponse.Size(m)
}
func (m *UpgradeReleaseResponse) XXX_DiscardUnknown() {
xxx_messageInfo_UpgradeReleaseResponse.DiscardUnknown(m)
}
var xxx_messageInfo_UpgradeReleaseResponse proto.InternalMessageInfo
func (m *UpgradeReleaseResponse) GetRelease() *hapi_release5.Release {
func (m *UpgradeReleaseResponse) GetRelease() *release.Release {
if m != nil {
return m.Release
}
@ -302,28 +480,50 @@ func (m *UpgradeReleaseResponse) GetResult() *Result {
}
type RollbackReleaseRequest struct {
Current *hapi_release5.Release `protobuf:"bytes,1,opt,name=current" json:"current,omitempty"`
Target *hapi_release5.Release `protobuf:"bytes,2,opt,name=target" json:"target,omitempty"`
Timeout int64 `protobuf:"varint,3,opt,name=Timeout" json:"Timeout,omitempty"`
Wait bool `protobuf:"varint,4,opt,name=Wait" json:"Wait,omitempty"`
Recreate bool `protobuf:"varint,5,opt,name=Recreate" json:"Recreate,omitempty"`
Force bool `protobuf:"varint,6,opt,name=Force" json:"Force,omitempty"`
CleanupOnFail bool `protobuf:"varint,7,opt,name=CleanupOnFail" json:"CleanupOnFail,omitempty"`
Current *release.Release `protobuf:"bytes,1,opt,name=current,proto3" json:"current,omitempty"`
Target *release.Release `protobuf:"bytes,2,opt,name=target,proto3" json:"target,omitempty"`
Timeout int64 `protobuf:"varint,3,opt,name=Timeout,proto3" json:"Timeout,omitempty"`
Wait bool `protobuf:"varint,4,opt,name=Wait,proto3" json:"Wait,omitempty"`
Recreate bool `protobuf:"varint,5,opt,name=Recreate,proto3" json:"Recreate,omitempty"`
Force bool `protobuf:"varint,6,opt,name=Force,proto3" json:"Force,omitempty"`
CleanupOnFail bool `protobuf:"varint,7,opt,name=CleanupOnFail,proto3" json:"CleanupOnFail,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *RollbackReleaseRequest) Reset() { *m = RollbackReleaseRequest{} }
func (m *RollbackReleaseRequest) String() string { return proto.CompactTextString(m) }
func (*RollbackReleaseRequest) ProtoMessage() {}
func (*RollbackReleaseRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} }
func (*RollbackReleaseRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rudder_dd8cdbe38a210d28, []int{9}
}
func (m *RollbackReleaseRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_RollbackReleaseRequest.Unmarshal(m, b)
}
func (m *RollbackReleaseRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_RollbackReleaseRequest.Marshal(b, m, deterministic)
}
func (dst *RollbackReleaseRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_RollbackReleaseRequest.Merge(dst, src)
}
func (m *RollbackReleaseRequest) XXX_Size() int {
return xxx_messageInfo_RollbackReleaseRequest.Size(m)
}
func (m *RollbackReleaseRequest) XXX_DiscardUnknown() {
xxx_messageInfo_RollbackReleaseRequest.DiscardUnknown(m)
}
var xxx_messageInfo_RollbackReleaseRequest proto.InternalMessageInfo
func (m *RollbackReleaseRequest) GetCurrent() *hapi_release5.Release {
func (m *RollbackReleaseRequest) GetCurrent() *release.Release {
if m != nil {
return m.Current
}
return nil
}
func (m *RollbackReleaseRequest) GetTarget() *hapi_release5.Release {
func (m *RollbackReleaseRequest) GetTarget() *release.Release {
if m != nil {
return m.Target
}
@ -366,16 +566,38 @@ func (m *RollbackReleaseRequest) GetCleanupOnFail() bool {
}
type RollbackReleaseResponse struct {
Release *hapi_release5.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"`
Result *Result `protobuf:"bytes,2,opt,name=result" json:"result,omitempty"`
Release *release.Release `protobuf:"bytes,1,opt,name=release,proto3" json:"release,omitempty"`
Result *Result `protobuf:"bytes,2,opt,name=result,proto3" json:"result,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *RollbackReleaseResponse) Reset() { *m = RollbackReleaseResponse{} }
func (m *RollbackReleaseResponse) String() string { return proto.CompactTextString(m) }
func (*RollbackReleaseResponse) ProtoMessage() {}
func (*RollbackReleaseResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} }
func (*RollbackReleaseResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rudder_dd8cdbe38a210d28, []int{10}
}
func (m *RollbackReleaseResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_RollbackReleaseResponse.Unmarshal(m, b)
}
func (m *RollbackReleaseResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_RollbackReleaseResponse.Marshal(b, m, deterministic)
}
func (dst *RollbackReleaseResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_RollbackReleaseResponse.Merge(dst, src)
}
func (m *RollbackReleaseResponse) XXX_Size() int {
return xxx_messageInfo_RollbackReleaseResponse.Size(m)
}
func (m *RollbackReleaseResponse) XXX_DiscardUnknown() {
xxx_messageInfo_RollbackReleaseResponse.DiscardUnknown(m)
}
func (m *RollbackReleaseResponse) GetRelease() *hapi_release5.Release {
var xxx_messageInfo_RollbackReleaseResponse proto.InternalMessageInfo
func (m *RollbackReleaseResponse) GetRelease() *release.Release {
if m != nil {
return m.Release
}
@ -390,15 +612,37 @@ func (m *RollbackReleaseResponse) GetResult() *Result {
}
type ReleaseStatusRequest struct {
Release *hapi_release5.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"`
Release *release.Release `protobuf:"bytes,1,opt,name=release,proto3" json:"release,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ReleaseStatusRequest) Reset() { *m = ReleaseStatusRequest{} }
func (m *ReleaseStatusRequest) String() string { return proto.CompactTextString(m) }
func (*ReleaseStatusRequest) ProtoMessage() {}
func (*ReleaseStatusRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} }
func (*ReleaseStatusRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_rudder_dd8cdbe38a210d28, []int{11}
}
func (m *ReleaseStatusRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ReleaseStatusRequest.Unmarshal(m, b)
}
func (m *ReleaseStatusRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ReleaseStatusRequest.Marshal(b, m, deterministic)
}
func (dst *ReleaseStatusRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_ReleaseStatusRequest.Merge(dst, src)
}
func (m *ReleaseStatusRequest) XXX_Size() int {
return xxx_messageInfo_ReleaseStatusRequest.Size(m)
}
func (m *ReleaseStatusRequest) XXX_DiscardUnknown() {
xxx_messageInfo_ReleaseStatusRequest.DiscardUnknown(m)
}
var xxx_messageInfo_ReleaseStatusRequest proto.InternalMessageInfo
func (m *ReleaseStatusRequest) GetRelease() *hapi_release5.Release {
func (m *ReleaseStatusRequest) GetRelease() *release.Release {
if m != nil {
return m.Release
}
@ -406,23 +650,45 @@ func (m *ReleaseStatusRequest) GetRelease() *hapi_release5.Release {
}
type ReleaseStatusResponse struct {
Release *hapi_release5.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"`
Info *hapi_release3.Info `protobuf:"bytes,2,opt,name=info" json:"info,omitempty"`
Release *release.Release `protobuf:"bytes,1,opt,name=release,proto3" json:"release,omitempty"`
Info *release.Info `protobuf:"bytes,2,opt,name=info,proto3" json:"info,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ReleaseStatusResponse) Reset() { *m = ReleaseStatusResponse{} }
func (m *ReleaseStatusResponse) String() string { return proto.CompactTextString(m) }
func (*ReleaseStatusResponse) ProtoMessage() {}
func (*ReleaseStatusResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} }
func (*ReleaseStatusResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_rudder_dd8cdbe38a210d28, []int{12}
}
func (m *ReleaseStatusResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ReleaseStatusResponse.Unmarshal(m, b)
}
func (m *ReleaseStatusResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ReleaseStatusResponse.Marshal(b, m, deterministic)
}
func (dst *ReleaseStatusResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_ReleaseStatusResponse.Merge(dst, src)
}
func (m *ReleaseStatusResponse) XXX_Size() int {
return xxx_messageInfo_ReleaseStatusResponse.Size(m)
}
func (m *ReleaseStatusResponse) XXX_DiscardUnknown() {
xxx_messageInfo_ReleaseStatusResponse.DiscardUnknown(m)
}
var xxx_messageInfo_ReleaseStatusResponse proto.InternalMessageInfo
func (m *ReleaseStatusResponse) GetRelease() *hapi_release5.Release {
func (m *ReleaseStatusResponse) GetRelease() *release.Release {
if m != nil {
return m.Release
}
return nil
}
func (m *ReleaseStatusResponse) GetInfo() *hapi_release3.Info {
func (m *ReleaseStatusResponse) GetInfo() *release.Info {
if m != nil {
return m.Info
}
@ -454,8 +720,9 @@ var _ grpc.ClientConn
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// Client API for ReleaseModuleService service
// ReleaseModuleServiceClient is the client API for ReleaseModuleService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type ReleaseModuleServiceClient interface {
Version(ctx context.Context, in *VersionReleaseRequest, opts ...grpc.CallOption) (*VersionReleaseResponse, error)
// InstallRelease requests installation of a chart as a new release.
@ -480,7 +747,7 @@ func NewReleaseModuleServiceClient(cc *grpc.ClientConn) ReleaseModuleServiceClie
func (c *releaseModuleServiceClient) Version(ctx context.Context, in *VersionReleaseRequest, opts ...grpc.CallOption) (*VersionReleaseResponse, error) {
out := new(VersionReleaseResponse)
err := grpc.Invoke(ctx, "/hapi.services.rudder.ReleaseModuleService/Version", in, out, c.cc, opts...)
err := c.cc.Invoke(ctx, "/hapi.services.rudder.ReleaseModuleService/Version", in, out, opts...)
if err != nil {
return nil, err
}
@ -489,7 +756,7 @@ func (c *releaseModuleServiceClient) Version(ctx context.Context, in *VersionRel
func (c *releaseModuleServiceClient) InstallRelease(ctx context.Context, in *InstallReleaseRequest, opts ...grpc.CallOption) (*InstallReleaseResponse, error) {
out := new(InstallReleaseResponse)
err := grpc.Invoke(ctx, "/hapi.services.rudder.ReleaseModuleService/InstallRelease", in, out, c.cc, opts...)
err := c.cc.Invoke(ctx, "/hapi.services.rudder.ReleaseModuleService/InstallRelease", in, out, opts...)
if err != nil {
return nil, err
}
@ -498,7 +765,7 @@ func (c *releaseModuleServiceClient) InstallRelease(ctx context.Context, in *Ins
func (c *releaseModuleServiceClient) DeleteRelease(ctx context.Context, in *DeleteReleaseRequest, opts ...grpc.CallOption) (*DeleteReleaseResponse, error) {
out := new(DeleteReleaseResponse)
err := grpc.Invoke(ctx, "/hapi.services.rudder.ReleaseModuleService/DeleteRelease", in, out, c.cc, opts...)
err := c.cc.Invoke(ctx, "/hapi.services.rudder.ReleaseModuleService/DeleteRelease", in, out, opts...)
if err != nil {
return nil, err
}
@ -507,7 +774,7 @@ func (c *releaseModuleServiceClient) DeleteRelease(ctx context.Context, in *Dele
func (c *releaseModuleServiceClient) RollbackRelease(ctx context.Context, in *RollbackReleaseRequest, opts ...grpc.CallOption) (*RollbackReleaseResponse, error) {
out := new(RollbackReleaseResponse)
err := grpc.Invoke(ctx, "/hapi.services.rudder.ReleaseModuleService/RollbackRelease", in, out, c.cc, opts...)
err := c.cc.Invoke(ctx, "/hapi.services.rudder.ReleaseModuleService/RollbackRelease", in, out, opts...)
if err != nil {
return nil, err
}
@ -516,7 +783,7 @@ func (c *releaseModuleServiceClient) RollbackRelease(ctx context.Context, in *Ro
func (c *releaseModuleServiceClient) UpgradeRelease(ctx context.Context, in *UpgradeReleaseRequest, opts ...grpc.CallOption) (*UpgradeReleaseResponse, error) {
out := new(UpgradeReleaseResponse)
err := grpc.Invoke(ctx, "/hapi.services.rudder.ReleaseModuleService/UpgradeRelease", in, out, c.cc, opts...)
err := c.cc.Invoke(ctx, "/hapi.services.rudder.ReleaseModuleService/UpgradeRelease", in, out, opts...)
if err != nil {
return nil, err
}
@ -525,15 +792,14 @@ func (c *releaseModuleServiceClient) UpgradeRelease(ctx context.Context, in *Upg
func (c *releaseModuleServiceClient) ReleaseStatus(ctx context.Context, in *ReleaseStatusRequest, opts ...grpc.CallOption) (*ReleaseStatusResponse, error) {
out := new(ReleaseStatusResponse)
err := grpc.Invoke(ctx, "/hapi.services.rudder.ReleaseModuleService/ReleaseStatus", in, out, c.cc, opts...)
err := c.cc.Invoke(ctx, "/hapi.services.rudder.ReleaseModuleService/ReleaseStatus", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for ReleaseModuleService service
// ReleaseModuleServiceServer is the server API for ReleaseModuleService service.
type ReleaseModuleServiceServer interface {
Version(context.Context, *VersionReleaseRequest) (*VersionReleaseResponse, error)
// InstallRelease requests installation of a chart as a new release.
@ -693,9 +959,9 @@ var _ReleaseModuleService_serviceDesc = grpc.ServiceDesc{
Metadata: "hapi/rudder/rudder.proto",
}
func init() { proto.RegisterFile("hapi/rudder/rudder.proto", fileDescriptor0) }
func init() { proto.RegisterFile("hapi/rudder/rudder.proto", fileDescriptor_rudder_dd8cdbe38a210d28) }
var fileDescriptor0 = []byte{
var fileDescriptor_rudder_dd8cdbe38a210d28 = []byte{
// 615 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x56, 0x4d, 0x6f, 0xd3, 0x40,
0x10, 0x8d, 0x9b, 0xc6, 0x69, 0xa6, 0x2a, 0x44, 0xab, 0xba, 0xb5, 0x2c, 0x0e, 0x91, 0x85, 0x50,

File diff suppressed because it is too large Load Diff

@ -1,15 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: hapi/version/version.proto
/*
Package version is a generated protocol buffer package.
It is generated from these files:
hapi/version/version.proto
It has these top-level messages:
Version
*/
package version
import proto "github.com/golang/protobuf/proto"
@ -29,15 +20,37 @@ const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type Version struct {
// Sem ver string for the version
SemVer string `protobuf:"bytes,1,opt,name=sem_ver,json=semVer" json:"sem_ver,omitempty"`
GitCommit string `protobuf:"bytes,2,opt,name=git_commit,json=gitCommit" json:"git_commit,omitempty"`
GitTreeState string `protobuf:"bytes,3,opt,name=git_tree_state,json=gitTreeState" json:"git_tree_state,omitempty"`
SemVer string `protobuf:"bytes,1,opt,name=sem_ver,json=semVer,proto3" json:"sem_ver,omitempty"`
GitCommit string `protobuf:"bytes,2,opt,name=git_commit,json=gitCommit,proto3" json:"git_commit,omitempty"`
GitTreeState string `protobuf:"bytes,3,opt,name=git_tree_state,json=gitTreeState,proto3" json:"git_tree_state,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Version) Reset() { *m = Version{} }
func (m *Version) String() string { return proto.CompactTextString(m) }
func (*Version) ProtoMessage() {}
func (*Version) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (*Version) Descriptor() ([]byte, []int) {
return fileDescriptor_version_227db6d1d83f2c17, []int{0}
}
func (m *Version) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Version.Unmarshal(m, b)
}
func (m *Version) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Version.Marshal(b, m, deterministic)
}
func (dst *Version) XXX_Merge(src proto.Message) {
xxx_messageInfo_Version.Merge(dst, src)
}
func (m *Version) XXX_Size() int {
return xxx_messageInfo_Version.Size(m)
}
func (m *Version) XXX_DiscardUnknown() {
xxx_messageInfo_Version.DiscardUnknown(m)
}
var xxx_messageInfo_Version proto.InternalMessageInfo
func (m *Version) GetSemVer() string {
if m != nil {
@ -64,9 +77,9 @@ func init() {
proto.RegisterType((*Version)(nil), "hapi.version.Version")
}
func init() { proto.RegisterFile("hapi/version/version.proto", fileDescriptor0) }
func init() { proto.RegisterFile("hapi/version/version.proto", fileDescriptor_version_227db6d1d83f2c17) }
var fileDescriptor0 = []byte{
var fileDescriptor_version_227db6d1d83f2c17 = []byte{
// 151 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0xca, 0x48, 0x2c, 0xc8,
0xd4, 0x2f, 0x4b, 0x2d, 0x2a, 0xce, 0xcc, 0xcf, 0x83, 0xd1, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9,

@ -404,6 +404,8 @@ func DigestFile(filename string) (string, error) {
// Helm uses SHA256 as its default hash for all non-cryptographic applications.
func Digest(in io.Reader) (string, error) {
hash := crypto.SHA256.New()
io.Copy(hash, in)
if _, err := io.Copy(hash, in); err != nil {
return "", nil
}
return hex.EncodeToString(hash.Sum(nil)), nil
}

@ -37,7 +37,8 @@ import (
tillerEnv "k8s.io/helm/pkg/tiller/environment"
)
const manifestWithTestSuccessHook = `
const (
manifestWithTestSuccessHook = `
apiVersion: v1
kind: Pod
metadata:
@ -51,7 +52,7 @@ spec:
cmd: fake-command
`
const manifestWithTestFailureHook = `
manifestWithTestFailureHook = `
apiVersion: v1
kind: Pod
metadata:
@ -64,7 +65,7 @@ spec:
image: fake-gold-finding-image
cmd: fake-gold-finding-command
`
const manifestWithInstallHooks = `apiVersion: v1
manifestWithInstallHooks = `apiVersion: v1
kind: ConfigMap
metadata:
name: test-cm
@ -73,6 +74,7 @@ metadata:
data:
name: value
`
)
func TestNewTestSuite(t *testing.T) {
rel := releaseStub()

@ -15,7 +15,6 @@ package driver
import (
"encoding/base64"
"reflect"
"testing"
"github.com/gogo/protobuf/proto"
@ -46,7 +45,7 @@ func TestConfigMapGet(t *testing.T) {
t.Fatalf("Failed to get release: %s", err)
}
// compare fetched release with original
if !reflect.DeepEqual(rel, got) {
if !shallowReleaseEqual(rel, got) {
t.Errorf("Expected {%q}, got {%q}", rel, got)
}
}
@ -78,7 +77,7 @@ func TestUNcompressedConfigMapGet(t *testing.T) {
t.Fatalf("Failed to get release: %s", err)
}
// compare fetched release with original
if !reflect.DeepEqual(rel, got) {
if !shallowReleaseEqual(rel, got) {
t.Errorf("Expected {%q}, got {%q}", rel, got)
}
}
@ -151,7 +150,7 @@ func TestConfigMapCreate(t *testing.T) {
}
// compare created release with original
if !reflect.DeepEqual(rel, got) {
if !shallowReleaseEqual(rel, got) {
t.Errorf("Expected {%q}, got {%q}", rel, got)
}
}

@ -20,6 +20,8 @@ import (
"fmt"
"testing"
sqlmock "github.com/DATA-DOG/go-sqlmock"
"github.com/jmoiron/sqlx"
"k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -38,6 +40,16 @@ func releaseStub(name string, vers int32, namespace string, code rspb.Status_Cod
}
}
func shallowReleaseEqual(r1 *rspb.Release, r2 *rspb.Release) bool {
if r1.Name != r2.Name ||
r1.Namespace != r2.Namespace ||
r1.Version != r2.Version ||
r1.Manifest != r2.Manifest {
return false
}
return true
}
func testKey(name string, vers int32) string {
return fmt.Sprintf("%s.v%d", name, vers)
}
@ -221,3 +233,17 @@ func (mock *MockSecretsInterface) Delete(name string, opts *metav1.DeleteOptions
delete(mock.objects, name)
return nil
}
// newTestFixtureSQL mocks the SQL database (for testing purposes)
func newTestFixtureSQL(t *testing.T, releases ...*rspb.Release) (*SQL, sqlmock.Sqlmock) {
sqlDB, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("error when opening stub database connection: %v", err)
}
sqlxDB := sqlx.NewDb(sqlDB, "sqlmock")
return &SQL{
db: sqlxDB,
Log: func(_ string, _ ...interface{}) {},
}, mock
}

@ -15,7 +15,6 @@ package driver
import (
"encoding/base64"
"reflect"
"testing"
"github.com/gogo/protobuf/proto"
@ -46,7 +45,7 @@ func TestSecretGet(t *testing.T) {
t.Fatalf("Failed to get release: %s", err)
}
// compare fetched release with original
if !reflect.DeepEqual(rel, got) {
if !shallowReleaseEqual(rel, got) {
t.Errorf("Expected {%q}, got {%q}", rel, got)
}
}
@ -78,7 +77,7 @@ func TestUNcompressedSecretGet(t *testing.T) {
t.Fatalf("Failed to get release: %s", err)
}
// compare fetched release with original
if !reflect.DeepEqual(rel, got) {
if !shallowReleaseEqual(rel, got) {
t.Errorf("Expected {%q}, got {%q}", rel, got)
}
}
@ -151,7 +150,7 @@ func TestSecretCreate(t *testing.T) {
}
// compare created release with original
if !reflect.DeepEqual(rel, got) {
if !shallowReleaseEqual(rel, got) {
t.Errorf("Expected {%q}, got {%q}", rel, got)
}
}

@ -0,0 +1,336 @@
/*
Copyright The Helm Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package driver
import (
"fmt"
"sort"
"strings"
"time"
"github.com/jmoiron/sqlx"
migrate "github.com/rubenv/sql-migrate"
// Import pq for potgres dialect
_ "github.com/lib/pq"
rspb "k8s.io/helm/pkg/proto/hapi/release"
storageerrors "k8s.io/helm/pkg/storage/errors"
)
var _ Driver = (*SQL)(nil)
var labelMap = map[string]string{
"MODIFIED_AT": "modified_at",
"CREATED_AT": "created_at",
"VERSION": "version",
"STATUS": "status",
"OWNER": "owner",
"NAME": "name",
}
var supportedSQLDialects = map[string]struct{}{
"postgres": {},
}
// SQLDriverName is the string name of this driver.
const SQLDriverName = "SQL"
// SQL is the sql storage driver implementation.
type SQL struct {
db *sqlx.DB
Log func(string, ...interface{})
}
// Name returns the name of the driver.
func (s *SQL) Name() string {
return SQLDriverName
}
func (s *SQL) ensureDBSetup() error {
// Populate the database with the relations we need if they don't exist yet
migrations := &migrate.MemoryMigrationSource{
Migrations: []*migrate.Migration{
{
Id: "init",
Up: []string{
`
CREATE TABLE releases (
key VARCHAR(67) PRIMARY KEY,
body TEXT NOT NULL,
name VARCHAR(64) NOT NULL,
version INTEGER NOT NULL,
status TEXT NOT NULL,
owner TEXT NOT NULL,
created_at INTEGER NOT NULL,
modified_at INTEGER NOT NULL DEFAULT 0
);
CREATE INDEX ON releases (key);
CREATE INDEX ON releases (version);
CREATE INDEX ON releases (status);
CREATE INDEX ON releases (owner);
CREATE INDEX ON releases (created_at);
CREATE INDEX ON releases (modified_at);
`,
},
Down: []string{
`
DROP TABLE releases;
`,
},
},
},
}
_, err := migrate.Exec(s.db.DB, "postgres", migrations, migrate.Up)
return err
}
// SQLReleaseWrapper describes how Helm releases are stored in an SQL database
type SQLReleaseWrapper struct {
// The primary key, made of {release-name}.{release-version}
Key string `db:"key"`
// The rspb.Release body, as a base64-encoded string
Body string `db:"body"`
// Release "labels" that can be used as filters in the storage.Query(labels map[string]string)
// we implemented. Note that allowing Helm users to filter against new dimensions will require a
// new migration to be added, and the Create and/or update functions to be updated accordingly.
Name string `db:"name"`
Version int `db:"version"`
Status string `db:"status"`
Owner string `db:"owner"`
CreatedAt int `db:"created_at"`
ModifiedAt int `db:"modified_at"`
}
// NewSQL initializes a new memory driver.
func NewSQL(dialect, connectionString string, logger func(string, ...interface{})) (*SQL, error) {
if _, ok := supportedSQLDialects[dialect]; !ok {
return nil, fmt.Errorf("%s dialect isn't supported, only \"postgres\" is available for now", dialect)
}
db, err := sqlx.Connect(dialect, connectionString)
if err != nil {
return nil, err
}
driver := &SQL{
db: db,
Log: logger,
}
if err := driver.ensureDBSetup(); err != nil {
return nil, err
}
return driver, nil
}
// Get returns the release named by key.
func (s *SQL) Get(key string) (*rspb.Release, error) {
var record SQLReleaseWrapper
// Get will return an error if the result is empty
err := s.db.Get(&record, "SELECT body FROM releases WHERE key = $1", key)
if err != nil {
s.Log("got SQL error when getting release %s: %v", key, err)
return nil, storageerrors.ErrReleaseNotFound(key)
}
release, err := decodeRelease(record.Body)
if err != nil {
s.Log("get: failed to decode data %q: %v", key, err)
return nil, err
}
return release, nil
}
// List returns the list of all releases such that filter(release) == true
func (s *SQL) List(filter func(*rspb.Release) bool) ([]*rspb.Release, error) {
var records = []SQLReleaseWrapper{}
if err := s.db.Select(&records, "SELECT body FROM releases WHERE owner = 'TILLER'"); err != nil {
s.Log("list: failed to list: %v", err)
return nil, err
}
var releases []*rspb.Release
for _, record := range records {
release, err := decodeRelease(record.Body)
if err != nil {
s.Log("list: failed to decode release: %v: %v", record, err)
continue
}
if filter(release) {
releases = append(releases, release)
}
}
return releases, nil
}
// Query returns the set of releases that match the provided set of labels.
func (s *SQL) Query(labels map[string]string) ([]*rspb.Release, error) {
var sqlFilterKeys []string
sqlFilter := map[string]interface{}{}
for key, val := range labels {
// Build a slice of where filters e.g
// labels = map[string]string{ "foo": "foo", "bar": "bar" }
// []string{ "foo=?", "bar=?" }
if dbField, ok := labelMap[key]; ok {
sqlFilterKeys = append(sqlFilterKeys, strings.Join([]string{dbField, "=:", dbField}, ""))
sqlFilter[dbField] = val
} else {
s.Log("unknown label %s", key)
return nil, fmt.Errorf("unknow label %s", key)
}
}
sort.Strings(sqlFilterKeys)
// Build our query
query := strings.Join([]string{
"SELECT body FROM releases",
"WHERE",
strings.Join(sqlFilterKeys, " AND "),
}, " ")
rows, err := s.db.NamedQuery(query, sqlFilter)
if err != nil {
s.Log("failed to query with labels: %v", err)
return nil, err
}
var releases []*rspb.Release
for rows.Next() {
var record SQLReleaseWrapper
if err = rows.StructScan(&record); err != nil {
s.Log("failed to scan record %q: %v", record, err)
return nil, err
}
release, err := decodeRelease(record.Body)
if err != nil {
s.Log("failed to decode release: %v", err)
continue
}
releases = append(releases, release)
}
if len(releases) == 0 {
return nil, storageerrors.ErrReleaseNotFound(labels["NAME"])
}
return releases, nil
}
// Create creates a new release.
func (s *SQL) Create(key string, rls *rspb.Release) error {
body, err := encodeRelease(rls)
if err != nil {
s.Log("failed to encode release: %v", err)
return err
}
transaction, err := s.db.Beginx()
if err != nil {
s.Log("failed to start SQL transaction: %v", err)
return fmt.Errorf("error beginning transaction: %v", err)
}
if _, err := transaction.NamedExec("INSERT INTO releases (key, body, name, version, status, owner, created_at) VALUES (:key, :body, :name, :version, :status, :owner, :created_at)",
&SQLReleaseWrapper{
Key: key,
Body: body,
Name: rls.Name,
Version: int(rls.Version),
Status: rspb.Status_Code_name[int32(rls.Info.Status.Code)],
Owner: "TILLER",
CreatedAt: int(time.Now().Unix()),
},
); err != nil {
defer transaction.Rollback()
var record SQLReleaseWrapper
if err := transaction.Get(&record, "SELECT key FROM releases WHERE key = ?", key); err == nil {
s.Log("release %s already exists", key)
return storageerrors.ErrReleaseExists(key)
}
s.Log("failed to store release %s in SQL database: %v", key, err)
return err
}
defer transaction.Commit()
return nil
}
// Update updates a release.
func (s *SQL) Update(key string, rls *rspb.Release) error {
body, err := encodeRelease(rls)
if err != nil {
s.Log("failed to encode release: %v", err)
return err
}
if _, err := s.db.NamedExec("UPDATE releases SET body=:body, name=:name, version=:version, status=:status, owner=:owner, modified_at=:modified_at WHERE key=:key",
&SQLReleaseWrapper{
Key: key,
Body: body,
Name: rls.Name,
Version: int(rls.Version),
Status: rspb.Status_Code_name[int32(rls.Info.Status.Code)],
Owner: "TILLER",
ModifiedAt: int(time.Now().Unix()),
},
); err != nil {
s.Log("failed to update release %s in SQL database: %v", key, err)
return err
}
return nil
}
// Delete deletes a release or returns ErrReleaseNotFound.
func (s *SQL) Delete(key string) (*rspb.Release, error) {
transaction, err := s.db.Beginx()
if err != nil {
s.Log("failed to start SQL transaction: %v", err)
return nil, fmt.Errorf("error beginning transaction: %v", err)
}
var record SQLReleaseWrapper
err = transaction.Get(&record, "SELECT body FROM releases WHERE key = $1", key)
if err != nil {
s.Log("release %s not found: %v", key, err)
return nil, storageerrors.ErrReleaseNotFound(key)
}
release, err := decodeRelease(record.Body)
if err != nil {
s.Log("failed to decode release %s: %v", key, err)
transaction.Rollback()
return nil, err
}
defer transaction.Commit()
_, err = transaction.Exec("DELETE FROM releases WHERE key = $1", key)
return release, err
}

@ -0,0 +1,346 @@
/*
Copyright The Helm Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package driver
import (
"fmt"
"regexp"
"testing"
"time"
sqlmock "github.com/DATA-DOG/go-sqlmock"
rspb "k8s.io/helm/pkg/proto/hapi/release"
)
func TestSQLName(t *testing.T) {
sqlDriver, _ := newTestFixtureSQL(t)
if sqlDriver.Name() != SQLDriverName {
t.Errorf("Expected name to be %q, got %q", SQLDriverName, sqlDriver.Name())
}
}
func TestSQLGet(t *testing.T) {
vers := int32(1)
name := "smug-pigeon"
namespace := "default"
key := testKey(name, vers)
rel := releaseStub(name, vers, namespace, rspb.Status_DEPLOYED)
body, err := encodeRelease(rel)
if err != nil {
t.Fatal(err)
}
sqlDriver, mock := newTestFixtureSQL(t)
mock.
ExpectQuery("SELECT body FROM releases WHERE key = ?").
WithArgs(key).
WillReturnRows(
mock.NewRows([]string{
"body",
}).AddRow(
body,
),
).RowsWillBeClosed()
got, err := sqlDriver.Get(key)
if err != nil {
t.Fatalf("Failed to get release: %v", err)
}
if !shallowReleaseEqual(rel, got) {
t.Errorf("Expected release {%q}, got {%q}", rel, got)
}
if err := mock.ExpectationsWereMet(); err != nil {
t.Errorf("sql expectations weren't met: %v", err)
}
}
func TestSQLList(t *testing.T) {
body1, _ := encodeRelease(releaseStub("key-1", 1, "default", rspb.Status_DELETED))
body2, _ := encodeRelease(releaseStub("key-2", 1, "default", rspb.Status_DELETED))
body3, _ := encodeRelease(releaseStub("key-3", 1, "default", rspb.Status_DEPLOYED))
body4, _ := encodeRelease(releaseStub("key-4", 1, "default", rspb.Status_DEPLOYED))
body5, _ := encodeRelease(releaseStub("key-5", 1, "default", rspb.Status_SUPERSEDED))
body6, _ := encodeRelease(releaseStub("key-6", 1, "default", rspb.Status_SUPERSEDED))
sqlDriver, mock := newTestFixtureSQL(t)
for i := 0; i < 3; i++ {
mock.
ExpectQuery("SELECT body FROM releases WHERE owner = 'TILLER'").
WillReturnRows(
mock.NewRows([]string{
"body",
}).
AddRow(body1).
AddRow(body2).
AddRow(body3).
AddRow(body4).
AddRow(body5).
AddRow(body6),
).RowsWillBeClosed()
}
// list all deleted releases
del, err := sqlDriver.List(func(rel *rspb.Release) bool {
return rel.Info.Status.Code == rspb.Status_DELETED
})
// check
if err != nil {
t.Errorf("Failed to list deleted: %v", err)
}
if len(del) != 2 {
t.Errorf("Expected 2 deleted, got %d:\n%v\n", len(del), del)
}
// list all deployed releases
dpl, err := sqlDriver.List(func(rel *rspb.Release) bool {
return rel.Info.Status.Code == rspb.Status_DEPLOYED
})
// check
if err != nil {
t.Errorf("Failed to list deployed: %v", err)
}
if len(dpl) != 2 {
t.Errorf("Expected 2 deployed, got %d:\n%v\n", len(dpl), dpl)
}
// list all superseded releases
ssd, err := sqlDriver.List(func(rel *rspb.Release) bool {
return rel.Info.Status.Code == rspb.Status_SUPERSEDED
})
// check
if err != nil {
t.Errorf("Failed to list superseded: %v", err)
}
if len(ssd) != 2 {
t.Errorf("Expected 2 superseded, got %d:\n%v\n", len(ssd), ssd)
}
if err := mock.ExpectationsWereMet(); err != nil {
t.Errorf("sql expectations weren't met: %v", err)
}
}
func TestSqlCreate(t *testing.T) {
vers := int32(1)
name := "smug-pigeon"
namespace := "default"
key := testKey(name, vers)
rel := releaseStub(name, vers, namespace, rspb.Status_DEPLOYED)
sqlDriver, mock := newTestFixtureSQL(t)
body, _ := encodeRelease(rel)
mock.ExpectBegin()
mock.
ExpectExec(regexp.QuoteMeta("INSERT INTO releases (key, body, name, version, status, owner, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)")).
WithArgs(key, body, rel.Name, int(rel.Version), rspb.Status_Code_name[int32(rel.Info.Status.Code)], "TILLER", int(time.Now().Unix())).
WillReturnResult(sqlmock.NewResult(1, 1))
mock.ExpectCommit()
if err := sqlDriver.Create(key, rel); err != nil {
t.Fatalf("failed to create release with key %q: %v", key, err)
}
if err := mock.ExpectationsWereMet(); err != nil {
t.Errorf("sql expectations weren't met: %v", err)
}
}
func TestSqlCreateAlreadyExists(t *testing.T) {
vers := int32(1)
name := "smug-pigeon"
namespace := "default"
key := testKey(name, vers)
rel := releaseStub(name, vers, namespace, rspb.Status_DEPLOYED)
sqlDriver, mock := newTestFixtureSQL(t)
body, _ := encodeRelease(rel)
// Insert fails (primary key already exists)
mock.ExpectBegin()
mock.
ExpectExec(regexp.QuoteMeta("INSERT INTO releases (key, body, name, version, status, owner, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)")).
WithArgs(key, body, rel.Name, int(rel.Version), rspb.Status_Code_name[int32(rel.Info.Status.Code)], "TILLER", int(time.Now().Unix())).
WillReturnError(fmt.Errorf("dialect dependent SQL error"))
// Let's check that we do make sure the error is due to a release already existing
mock.
ExpectQuery(regexp.QuoteMeta("SELECT key FROM releases WHERE key = ?")).
WithArgs(key).
WillReturnRows(
mock.NewRows([]string{
"body",
}).AddRow(
body,
),
).RowsWillBeClosed()
mock.ExpectRollback()
if err := sqlDriver.Create(key, rel); err == nil {
t.Fatalf("failed to create release with key %q: %v", key, err)
}
if err := mock.ExpectationsWereMet(); err != nil {
t.Errorf("sql expectations weren't met: %v", err)
}
}
func TestSqlUpdate(t *testing.T) {
vers := int32(1)
name := "smug-pigeon"
namespace := "default"
key := testKey(name, vers)
rel := releaseStub(name, vers, namespace, rspb.Status_DEPLOYED)
sqlDriver, mock := newTestFixtureSQL(t)
body, _ := encodeRelease(rel)
mock.
ExpectExec(regexp.QuoteMeta("UPDATE releases SET body=?, name=?, version=?, status=?, owner=?, modified_at=? WHERE key=?")).
WithArgs(body, rel.Name, int(rel.Version), rspb.Status_Code_name[int32(rel.Info.Status.Code)], "TILLER", int(time.Now().Unix()), key).
WillReturnResult(sqlmock.NewResult(0, 1))
if err := sqlDriver.Update(key, rel); err != nil {
t.Fatalf("failed to update release with key %q: %v", key, err)
}
if err := mock.ExpectationsWereMet(); err != nil {
t.Errorf("sql expectations weren't met: %v", err)
}
}
func TestSqlQuery(t *testing.T) {
// Reflect actual use cases in ../storage.go
labelSetDeployed := map[string]string{
"NAME": "smug-pigeon",
"OWNER": "TILLER",
"STATUS": "DEPLOYED",
}
labelSetAll := map[string]string{
"NAME": "smug-pigeon",
"OWNER": "TILLER",
}
supersededRelease := releaseStub("smug-pigeon", 1, "default", rspb.Status_SUPERSEDED)
supersededReleaseBody, _ := encodeRelease(supersededRelease)
deployedRelease := releaseStub("smug-pigeon", 2, "default", rspb.Status_DEPLOYED)
deployedReleaseBody, _ := encodeRelease(deployedRelease)
// Let's actually start our test
sqlDriver, mock := newTestFixtureSQL(t)
mock.
ExpectQuery(regexp.QuoteMeta("SELECT body FROM releases WHERE name=? AND owner=? AND status=?")).
WithArgs("smug-pigeon", "TILLER", "DEPLOYED").
WillReturnRows(
mock.NewRows([]string{
"body",
}).AddRow(
deployedReleaseBody,
),
).RowsWillBeClosed()
mock.
ExpectQuery(regexp.QuoteMeta("SELECT body FROM releases WHERE name=? AND owner=?")).
WithArgs("smug-pigeon", "TILLER").
WillReturnRows(
mock.NewRows([]string{
"body",
}).AddRow(
supersededReleaseBody,
).AddRow(
deployedReleaseBody,
),
).RowsWillBeClosed()
results, err := sqlDriver.Query(labelSetDeployed)
if err != nil {
t.Fatalf("failed to query for deployed smug-pigeon release: %v", err)
}
for _, res := range results {
if !shallowReleaseEqual(res, deployedRelease) {
t.Errorf("Expected release {%q}, got {%q}", deployedRelease, res)
}
}
results, err = sqlDriver.Query(labelSetAll)
if err != nil {
t.Fatalf("failed to query release history for smug-pigeon: %v", err)
}
if len(results) != 2 {
t.Errorf("expected a resultset of size 2, got %d", len(results))
}
for _, res := range results {
if !shallowReleaseEqual(res, deployedRelease) && !shallowReleaseEqual(res, supersededRelease) {
t.Errorf("Expected release {%q} or {%q}, got {%q}", deployedRelease, supersededRelease, res)
}
}
if err := mock.ExpectationsWereMet(); err != nil {
t.Errorf("sql expectations weren't met: %v", err)
}
}
func TestSqlDelete(t *testing.T) {
vers := int32(1)
name := "smug-pigeon"
namespace := "default"
key := testKey(name, vers)
rel := releaseStub(name, vers, namespace, rspb.Status_DEPLOYED)
body, _ := encodeRelease(rel)
sqlDriver, mock := newTestFixtureSQL(t)
mock.ExpectBegin()
mock.
ExpectQuery("SELECT body FROM releases WHERE key = ?").
WithArgs(key).
WillReturnRows(
mock.NewRows([]string{
"body",
}).AddRow(
body,
),
).RowsWillBeClosed()
mock.
ExpectExec(regexp.QuoteMeta("DELETE FROM releases WHERE key = $1")).
WithArgs(key).
WillReturnResult(sqlmock.NewResult(0, 1))
mock.ExpectCommit()
deletedRelease, err := sqlDriver.Delete(key)
if err != nil {
t.Fatalf("failed to delete release with key %q: %v", key, err)
}
if !shallowReleaseEqual(rel, deletedRelease) {
t.Errorf("Expected release {%q}, got {%q}", rel, deletedRelease)
}
if err := mock.ExpectationsWereMet(); err != nil {
t.Errorf("sql expectations weren't met: %v", err)
}
}

@ -37,11 +37,19 @@ import (
"k8s.io/helm/pkg/storage/driver"
)
const (
// DefaultTillerNamespace is the default namespace for Tiller.
const DefaultTillerNamespace = "kube-system"
DefaultTillerNamespace = "kube-system"
// DefaultTillerPort defines the default port tiller listen on for client traffic
DefaultTillerPort = 44134
// DefaultTillerProbePort defines the default port to listen on for probes
DefaultTillerProbePort = 44135
// GoTplEngine is the name of the Go template engine, as registered in the EngineYard.
const GoTplEngine = "gotpl"
GoTplEngine = "gotpl"
)
// DefaultEngine points to the engine that the EngineYard should treat as the
// default. A chart that does not specify an engine may be run through the
@ -144,6 +152,8 @@ type KubeClient interface {
// WaitAndGetCompletedPodPhase waits up to a timeout until a pod enters a completed phase
// and returns said phase (PodSucceeded or PodFailed qualify).
WaitAndGetCompletedPodPhase(namespace string, reader io.Reader, timeout time.Duration) (v1.PodPhase, error)
WaitUntilCRDEstablished(reader io.Reader, timeout time.Duration) error
}
// PrintingKubeClient implements KubeClient, but simply prints the reader to
@ -210,6 +220,11 @@ func (p *PrintingKubeClient) WaitAndGetCompletedPodPhase(namespace string, reade
return v1.PodUnknown, err
}
func (p *PrintingKubeClient) WaitUntilCRDEstablished(reader io.Reader, timeout time.Duration) error {
_, err := io.Copy(p.Out, reader)
return err
}
// Environment provides the context for executing a client request.
//
// All services in a context are concurrency safe.

@ -72,6 +72,10 @@ func (k *mockKubeClient) WaitAndGetCompletedPodStatus(namespace string, reader i
return "", nil
}
func (k *mockKubeClient) WaitUntilCRDEstablished(reader io.Reader, timeout time.Duration) error {
return nil
}
var _ Engine = &mockEngine{}
var _ KubeClient = &mockKubeClient{}
var _ KubeClient = &PrintingKubeClient{}

@ -23,6 +23,7 @@ import (
"path"
"regexp"
"strings"
"time"
"github.com/technosophos/moniker"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -40,18 +41,20 @@ import (
"k8s.io/helm/pkg/version"
)
const (
// releaseNameMaxLen is the maximum length of a release name.
//
// As of Kubernetes 1.4, the max limit on a name is 63 chars. We reserve 10 for
// charts to add data. Effectively, that gives us 53 chars.
// See https://github.com/kubernetes/helm/issues/1528
const releaseNameMaxLen = 53
releaseNameMaxLen = 53
// NOTESFILE_SUFFIX that we want to treat special. It goes through the templating engine
// but it's not a yaml file (resource) hence can't have hooks, etc. And the user actually
// wants to see this file after rendering in the status command. However, it must be a suffix
// since there can be filepath in front of it.
const notesFileSuffix = "NOTES.txt"
notesFileSuffix = "NOTES.txt"
)
var (
// errMissingChart indicates that a chart was not provided.
@ -399,7 +402,7 @@ func (s *ReleaseServer) execHook(hs []*release.Hook, name, namespace, hook strin
b.Reset()
b.WriteString(h.Manifest)
// We can't watch CRDs
// We can't watch CRDs, but need to wait until they reach the established state before continuing
if hook != hooks.CRDInstall {
if err := kubeCli.WatchUntilReady(namespace, b, timeout, false); err != nil {
s.Log("warning: Release %s %s %s could not complete: %s", name, hook, h.Path, err)
@ -410,6 +413,11 @@ func (s *ReleaseServer) execHook(hs []*release.Hook, name, namespace, hook strin
}
return err
}
} else {
if err := kubeCli.WaitUntilCRDEstablished(b, time.Duration(timeout)*time.Second); err != nil {
s.Log("warning: Release %s %s %s could not complete: %s", name, hook, h.Path, err)
return err
}
}
}

@ -654,6 +654,10 @@ func (kc *mockHooksKubeClient) WaitAndGetCompletedPodPhase(namespace string, rea
return v1.PodUnknown, nil
}
func (kc *mockHooksKubeClient) WaitUntilCRDEstablished(reader io.Reader, timeout time.Duration) error {
return nil
}
func deletePolicyStub(kubeClient *mockHooksKubeClient) *ReleaseServer {
e := environment.New()
e.Releases = storage.Init(driver.NewMemory())

@ -26,7 +26,7 @@ var (
// Increment major number for new feature additions and behavioral changes.
// Increment minor number for bug fixes and performance enhancements.
// Increment patch number for critical fixes to existing releases.
Version = "v2.12"
Version = "v2.14"
// BuildMetadata is extra build time data
BuildMetadata = "unreleased"

@ -39,9 +39,17 @@ func TestGetVersionProto(t *testing.T) {
BuildMetadata = tt.buildMetadata
GitCommit = tt.gitCommit
GitTreeState = tt.gitTreeState
if versionProto := GetVersionProto(); *versionProto != tt.expected {
t.Errorf("expected Semver(%s), GitCommit(%s) and GitTreeState(%s) to be %v", tt.expected, tt.gitCommit, tt.gitTreeState, *versionProto)
if versionProto := GetVersionProto(); !versionEqual(*versionProto, tt.expected) {
t.Errorf("expected Semver(%s+%s), GitCommit(%s) and GitTreeState(%s) to be %v", tt.version, tt.buildMetadata, tt.gitCommit, tt.gitTreeState, *versionProto)
}
}
}
func versionEqual(v1 version.Version, v2 version.Version) bool {
if v1.SemVer != v2.SemVer ||
v1.GitCommit != v2.GitCommit ||
v1.GitTreeState != v2.GitTreeState {
return false
}
return true
}

@ -12,9 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
FROM alpine:3.7
FROM alpine:3.9
RUN apk update && apk add ca-certificates socat && rm -rf /var/cache/apk/*
RUN apk add --no-cache ca-certificates socat
ENV HOME /tmp
@ -24,4 +24,3 @@ COPY tiller /tiller
EXPOSE 44134
USER 65534
ENTRYPOINT ["/tiller"]

@ -12,9 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
FROM alpine:3.7
FROM alpine:3.9
RUN apk update && apk add ca-certificates && rm -rf /var/cache/apk/*
RUN apk add --no-cache ca-certificates
ENV HOME /tmp
@ -23,4 +23,3 @@ COPY tiller /tiller
EXPOSE 44134
USER 65534
ENTRYPOINT ["/tiller", "--experimental-release"]

@ -12,9 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
FROM alpine:3.3
FROM alpine:3.9
RUN apk update && apk add ca-certificates && rm -rf /var/cache/apk/*
RUN apk add --no-cache ca-certificates
ENV HOME /tmp

Loading…
Cancel
Save