Merge remote-tracking branch 'upstream/master'

pull/3955/head
Andreas Bieber 8 years ago
commit f522cc0128

@ -31,7 +31,7 @@ build:
.PHONY: build-cross
build-cross: LDFLAGS += -extldflags "-static"
build-cross:
CGO_ENABLED=0 gox -parallel=3 -output="_dist/{{.OS}}-{{.Arch}}/{{.Dir}}" -osarch='$(TARGETS)' $(GOFLAGS) -tags '$(TAGS)' -ldflags '$(LDFLAGS)' k8s.io/helm/cmd/$(APP)
CGO_ENABLED=0 gox -parallel=3 -output="_dist/{{.OS}}-{{.Arch}}/{{.Dir}}" -osarch='$(TARGETS)' $(GOFLAGS) $(if $(TAGS),-tags '$(TAGS)',) -ldflags '$(LDFLAGS)' k8s.io/helm/cmd/$(APP)
.PHONY: dist
dist:

@ -73,7 +73,7 @@ func Upgrade(client kubernetes.Interface, opts *Options) error {
if _, err := client.ExtensionsV1beta1().Deployments(opts.Namespace).Update(obj); err != nil {
return err
}
// If the service does not exists that would mean we are upgrading from a Tiller version
// If the service does not exist that would mean we are upgrading from a Tiller version
// that didn't deploy the service, so install it.
_, err = client.CoreV1().Services(opts.Namespace).Get(serviceName, metav1.GetOptions{})
if apierrors.IsNotFound(err) {
@ -176,7 +176,6 @@ func generateDeployment(opts *Options) (*v1beta1.Deployment, error) {
return nil, err
}
}
automountServiceAccountToken := opts.ServiceAccount != ""
d := &v1beta1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Namespace: opts.Namespace,
@ -191,7 +190,6 @@ func generateDeployment(opts *Options) (*v1beta1.Deployment, error) {
},
Spec: v1.PodSpec{
ServiceAccountName: opts.ServiceAccount,
AutomountServiceAccountToken: &automountServiceAccountToken,
Containers: []v1.Container{
{
Name: "tiller",

@ -96,9 +96,6 @@ func TestDeploymentManifestForServiceAccount(t *testing.T) {
if got := d.Spec.Template.Spec.ServiceAccountName; got != tt.serviceAccount {
t.Errorf("%s: expected service account value %q, got %q", tt.name, tt.serviceAccount, got)
}
if got := *d.Spec.Template.Spec.AutomountServiceAccountToken; got != (tt.serviceAccount != "") {
t.Errorf("%s: unexpected automountServiceAccountToken = %t for serviceAccount %q", tt.name, got, tt.serviceAccount)
}
}
}

@ -131,7 +131,7 @@ func manuallyProcessArgs(args []string) ([]string, []string) {
switch a := args[i]; a {
case "--debug":
known = append(known, a)
case "--host", "--kube-context", "--home":
case "--host", "--kube-context", "--home", "--tiller-namespace":
known = append(known, a, args[i+1])
i++
default:

@ -47,6 +47,7 @@ type searchCmd struct {
versions bool
regexp bool
version string
colWidth uint
}
func newSearchCmd(out io.Writer) *cobra.Command {
@ -66,6 +67,7 @@ func newSearchCmd(out io.Writer) *cobra.Command {
f.BoolVarP(&sc.regexp, "regexp", "r", false, "use regular expressions for searching")
f.BoolVarP(&sc.versions, "versions", "l", false, "show the long listing, with each version of each chart on its own line")
f.StringVarP(&sc.version, "version", "v", "", "search using semantic versioning constraints")
f.UintVar(&sc.colWidth, "col-width", 60, "specifies the max column width of output")
return cmd
}
@ -93,7 +95,7 @@ func (s *searchCmd) run(args []string) error {
return err
}
fmt.Fprintln(s.out, s.formatSearchResults(data))
fmt.Fprintln(s.out, s.formatSearchResults(data, s.colWidth))
return nil
}
@ -126,12 +128,12 @@ func (s *searchCmd) applyConstraint(res []*search.Result) ([]*search.Result, err
return data, nil
}
func (s *searchCmd) formatSearchResults(res []*search.Result) string {
func (s *searchCmd) formatSearchResults(res []*search.Result, colWidth uint) string {
if len(res) == 0 {
return "No results found"
}
table := uitable.New()
table.MaxColWidth = 50
table.MaxColWidth = colWidth
table.AddRow("NAME", "CHART VERSION", "APP VERSION", "DESCRIPTION")
for _, r := range res {
table.AddRow(r.Name, r.Chart.Version, r.Chart.AppVersion, r.Chart.Description)

@ -119,9 +119,10 @@ You have multiple options with Globs:
```yaml
{{ range $path := .Files.Glob "**.yaml" }}
{{ $path }}: |
{{ .Files.Get $path }}
{{ $root := . }}
{{ range $path, $bytes := .Files.Glob "**.yaml" }}
{{ $path }}: |-
{{ $root.Files.Get $path }}
{{ end }}
```
@ -129,7 +130,7 @@ Or
```yaml
{{ range $path, $bytes := .Files.Glob "foo/*" }}
{{ $path }}: '{{ b64enc $bytes }}'
{{ $path.base }}: '{{ $root.Files.Get $path | b64enc }}'
{{ end }}
```

@ -19,6 +19,7 @@ helm search [keyword]
### Options
```
--col-width uint specifies the max column width of output (default 60)
-r, --regexp use regular expressions for searching
-v, --version string search using semantic versioning constraints
-l, --versions show the long listing, with each version of each chart on its own line
@ -38,4 +39,4 @@ helm search [keyword]
### SEE ALSO
* [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 8-Mar-2018
###### Auto generated by spf13/cobra on 23-Apr-2018

@ -183,7 +183,7 @@ If a plugin specifies `useTunnel: true`, Helm will do the following (in order):
5. Close the tunnel
The tunnel is removed as soon as the `command` returns. So, for example, a
command cannot background a process and assume that that process will be able
command cannot background a process and assume that process will be able
to use the tunnel.
## A Note on Flag Parsing

@ -53,7 +53,7 @@ This situation may change in the future. While the community has several methods
In the default installation the gRPC endpoint that Tiller offers is available inside the cluster (not external to the cluster) without authentication configuration applied. Without applying authentication, any process in the cluster can use the gRPC endpoint to perform operations inside the cluster. In a local or secured private cluster, this enables rapid usage and is normal. (When running outside the cluster, Helm authenticates through the Kubernetes API server to reach Tiller, leveraging existing Kubernetes authentication support.)
Shared and production clusters -- for the most part -- should use Helm 2.7.2 at a minimum and configure TLS for each Tiller gRPC endpoint to ensure that within the cluster usage of gRPC endpoints is only for the properly authenticated identity for that endpoint. Doing so enables any number of Tiller instances to be deployed in any number of namespaces and yet no unauthenticated usage of any gRPC endpoint is possible. Finally, usa Helm `init` with the `--tiller-tls-verify` option to install Tiller with TLS enabled and to verify remote certificates, and all other Helm commands should use the `--tls` option.
Shared and production clusters -- for the most part -- should use Helm 2.7.2 at a minimum and configure TLS for each Tiller gRPC endpoint to ensure that within the cluster usage of gRPC endpoints is only for the properly authenticated identity for that endpoint. Doing so enables any number of Tiller instances to be deployed in any number of namespaces and yet no unauthenticated usage of any gRPC endpoint is possible. Finally, use Helm `init` with the `--tiller-tls-verify` option to install Tiller with TLS enabled and to verify remote certificates, and all other Helm commands should use the `--tls` option.
For more information about the proper steps to configure Tiller and use Helm properly with TLS configured, see [Using SSL between Helm and Tiller](tiller_ssl.md).
@ -95,9 +95,9 @@ If these steps are followed, an example `helm init` command might look something
$ helm init \
--tiller-tls \
--tiller-tls-verify \
--tiller-tls-ca-cert=ca.pem \
--tiller-tls-cert=cert.pem \
--tiller-tls-key=key.pem \
--tls-ca-cert=ca.pem \
--service-account=accountname
```

@ -143,14 +143,14 @@ spec:
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ . }}
- host: {{ . | quote }}
http:
paths:
- path: {{ $ingressPath }}
@ -307,8 +307,9 @@ func CreateFrom(chartfile *chart.Metadata, dest string, src string) error {
}
schart.Templates = updatedTemplates
if schart.Values != nil {
schart.Values = &chart.Config{Raw: string(Transform(schart.Values.Raw, "<CHARTNAME>", schart.Metadata.Name))}
}
return SaveDir(schart, dest)
}

@ -175,7 +175,7 @@ func ToYaml(v interface{}) string {
// Swallow errors inside of a template.
return ""
}
return strings.TrimSuffix(string(data), "\n")
return string(data)
}
// FromYaml converts a YAML document into a map[string]interface{}.
@ -211,7 +211,8 @@ func ToToml(v interface{}) string {
// always return a string, even on marshal error (empty string).
//
// This is designed to be called from a template.
func ToJson(v interface{}) string {
// TODO: change the function signature in Helm 3
func ToJson(v interface{}) string { // nolint
data, err := json.Marshal(v)
if err != nil {
// Swallow errors inside of a template.
@ -226,7 +227,8 @@ func ToJson(v interface{}) string {
// JSON documents. Additionally, because its intended use is within templates
// it tolerates errors. It will insert the returned error message string into
// m["Error"] in the returned map.
func FromJson(str string) map[string]interface{} {
// TODO: change the function signature in Helm 3
func FromJson(str string) map[string]interface{} { // nolint
m := map[string]interface{}{}
if err := json.Unmarshal([]byte(str), &m); err != nil {

@ -72,10 +72,10 @@ func TestToConfig(t *testing.T) {
f := NewFiles(getTestFiles())
out := f.Glob("**/captain.txt").AsConfig()
as.Equal("captain.txt: The Captain", out)
as.Equal("captain.txt: The Captain\n", out)
out = f.Glob("ship/**").AsConfig()
as.Equal("captain.txt: The Captain\nstowaway.txt: Legatt", out)
as.Equal("captain.txt: The Captain\nstowaway.txt: Legatt\n", out)
}
func TestToSecret(t *testing.T) {
@ -84,7 +84,7 @@ func TestToSecret(t *testing.T) {
f := NewFiles(getTestFiles())
out := f.Glob("ship/**").AsSecrets()
as.Equal("captain.txt: VGhlIENhcHRhaW4=\nstowaway.txt: TGVnYXR0", out)
as.Equal("captain.txt: VGhlIENhcHRhaW4=\nstowaway.txt: TGVnYXR0\n", out)
}
func TestLines(t *testing.T) {
@ -99,7 +99,7 @@ func TestLines(t *testing.T) {
}
func TestToYaml(t *testing.T) {
expect := "foo: bar"
expect := "foo: bar\n"
v := struct {
Foo string `json:"foo"`
}{

@ -85,7 +85,7 @@ type ChartDownloader struct {
// Returns a string path to the location where the file was downloaded and a verification
// (if provenance was verified), or an error if something bad happened.
func (c *ChartDownloader) DownloadTo(ref, version, dest string) (string, *provenance.Verification, error) {
u, r, g, err := c.ResolveChartVersionAndGetRepo(ref, version)
u, g, err := c.ResolveChartVersion(ref, version)
if err != nil {
return "", nil, err
}
@ -104,7 +104,7 @@ func (c *ChartDownloader) DownloadTo(ref, version, dest string) (string, *proven
// If provenance is requested, verify it.
ver := &provenance.Verification{}
if c.Verify > VerifyNever {
body, err := r.Client.Get(u.String() + ".prov")
body, err := g.Get(u.String() + ".prov")
if err != nil {
if c.Verify == VerifyAlways {
return destfile, ver, fmt.Errorf("Failed to fetch provenance %q", u.String()+".prov")
@ -144,28 +144,14 @@ func (c *ChartDownloader) DownloadTo(ref, version, dest string) (string, *proven
// * If version is empty, this will return the URL for the latest version
// * If no version can be found, an error is returned
func (c *ChartDownloader) ResolveChartVersion(ref, version string) (*url.URL, getter.Getter, error) {
u, r, _, err := c.ResolveChartVersionAndGetRepo(ref, version)
if r != nil {
return u, r.Client, err
}
return u, nil, err
}
// ResolveChartVersionAndGetRepo is the same as the ResolveChartVersion method, but returns the chart repositoryy.
func (c *ChartDownloader) ResolveChartVersionAndGetRepo(ref, version string) (*url.URL, *repo.ChartRepository, *getter.HttpGetter, error) {
u, err := url.Parse(ref)
if err != nil {
return nil, nil, nil, fmt.Errorf("invalid chart URL format: %s", ref)
return nil, nil, fmt.Errorf("invalid chart URL format: %s", ref)
}
rf, err := repo.LoadRepositoriesFile(c.HelmHome.RepositoryFile())
if err != nil {
return u, nil, nil, err
}
g, err := getter.NewHTTPGetter(ref, "", "", "")
if err != nil {
return u, nil, nil, err
return u, nil, err
}
if u.IsAbs() && len(u.Host) > 0 && len(u.Path) > 0 {
@ -180,23 +166,26 @@ func (c *ChartDownloader) ResolveChartVersionAndGetRepo(ref, version string) (*u
// If there is no special config, return the default HTTP client and
// swallow the error.
if err == ErrNoOwnerRepo {
r := &repo.ChartRepository{}
r.Client = g
g.SetCredentials(c.getRepoCredentials(r))
return u, r, g, err
getterConstructor, err := c.Getters.ByScheme(u.Scheme)
if err != nil {
return u, nil, err
}
getter, err := getterConstructor(ref, "", "", "")
return u, getter, err
}
return u, nil, nil, err
return u, nil, err
}
r, err := repo.NewChartRepository(rc, c.Getters)
c.setCredentials(r)
// If we get here, we don't need to go through the next phase of looking
// up the URL. We have it already. So we just return.
return u, r, g, err
return u, r.Client, err
}
// See if it's of the form: repo/path_to_chart
p := strings.SplitN(u.Path, "/", 2)
if len(p) < 2 {
return u, nil, nil, fmt.Errorf("Non-absolute URLs should be in form of repo_name/path_to_chart, got: %s", u)
return u, nil, fmt.Errorf("Non-absolute URLs should be in form of repo_name/path_to_chart, got: %s", u)
}
repoName := p[0]
@ -204,56 +193,58 @@ func (c *ChartDownloader) ResolveChartVersionAndGetRepo(ref, version string) (*u
rc, err := pickChartRepositoryConfigByName(repoName, rf.Repositories)
if err != nil {
return u, nil, nil, err
return u, nil, err
}
r, err := repo.NewChartRepository(rc, c.Getters)
if err != nil {
return u, nil, nil, err
return u, nil, err
}
g.SetCredentials(c.getRepoCredentials(r))
c.setCredentials(r)
// Next, we need to load the index, and actually look up the chart.
i, err := repo.LoadIndexFile(c.HelmHome.CacheIndex(r.Config.Name))
if err != nil {
return u, r, g, fmt.Errorf("no cached repo found. (try 'helm repo update'). %s", err)
return u, r.Client, fmt.Errorf("no cached repo found. (try 'helm repo update'). %s", err)
}
cv, err := i.Get(chartName, version)
if err != nil {
return u, r, g, fmt.Errorf("chart %q matching %s not found in %s index. (try 'helm repo update'). %s", chartName, version, r.Config.Name, err)
return u, r.Client, fmt.Errorf("chart %q matching %s not found in %s index. (try 'helm repo update'). %s", chartName, version, r.Config.Name, err)
}
if len(cv.URLs) == 0 {
return u, r, g, fmt.Errorf("chart %q has no downloadable URLs", ref)
return u, r.Client, fmt.Errorf("chart %q has no downloadable URLs", ref)
}
// TODO: Seems that picking first URL is not fully correct
u, err = url.Parse(cv.URLs[0])
if err != nil {
return u, r, g, fmt.Errorf("invalid chart URL format: %s", ref)
return u, r.Client, fmt.Errorf("invalid chart URL format: %s", ref)
}
// If the URL is relative (no scheme), prepend the chart repo's base URL
if !u.IsAbs() {
repoURL, err := url.Parse(rc.URL)
if err != nil {
return repoURL, r, nil, err
return repoURL, r.Client, err
}
q := repoURL.Query()
// We need a trailing slash for ResolveReference to work, but make sure there isn't already one
repoURL.Path = strings.TrimSuffix(repoURL.Path, "/") + "/"
u = repoURL.ResolveReference(u)
u.RawQuery = q.Encode()
g, err := getter.NewHTTPGetter(rc.URL, "", "", "")
if err != nil {
return repoURL, r, nil, err
return u, r.Client, err
}
g.SetCredentials(c.getRepoCredentials(r))
return u, r, g, err
return u, r.Client, nil
}
return u, r, g, nil
// If HttpGetter is used, this method sets the configured repository credentials on the HttpGetter.
func (c *ChartDownloader) setCredentials(r *repo.ChartRepository) {
if t, ok := r.Client.(*getter.HttpGetter); ok {
t.SetCredentials(c.getRepoCredentials(r))
}
}
// If this ChartDownloader is not configured to use credentials, and the chart repository sent as an argument is,

@ -77,7 +77,7 @@ func (r *Rules) Len() int {
return len(r.patterns)
}
// Ignore evalutes the file at the given path, and returns true if it should be ignored.
// Ignore evaluates the file at the given path, and returns true if it should be ignored.
//
// Ignore evaluates path against the rules in order. Evaluation stops when a match
// is found. Matching a negative rule will stop evaluation.

@ -178,7 +178,7 @@ func (c *Client) Get(namespace string, reader io.Reader) (string, error) {
// versions per cluster, but this certainly won't hurt anything, so let's be safe.
gvk := info.ResourceMapping().GroupVersionKind
vk := gvk.Version + "/" + gvk.Kind
objs[vk] = append(objs[vk], info.Object)
objs[vk] = append(objs[vk], info.AsInternal())
//Get the relation pods
objPods, err = c.getSelectRelationPod(info, objPods)

@ -119,12 +119,9 @@ func (r *ChartRepository) DownloadIndexFile(cachePath string) error {
parsedURL.Path = strings.TrimSuffix(parsedURL.Path, "/") + "/index.yaml"
indexURL = parsedURL.String()
g, err := getter.NewHTTPGetter(indexURL, r.Config.CertFile, r.Config.KeyFile, r.Config.CAFile)
if err != nil {
return err
}
g.SetCredentials(r.Config.Username, r.Config.Password)
resp, err := g.Get(indexURL)
r.setCredentials()
resp, err := r.Client.Get(indexURL)
if err != nil {
return err
}
@ -152,6 +149,13 @@ func (r *ChartRepository) DownloadIndexFile(cachePath string) error {
return ioutil.WriteFile(cp, index, 0644)
}
// If HttpGetter is used, this method sets the configured repository credentials on the HttpGetter.
func (r *ChartRepository) setCredentials() {
if t, ok := r.Client.(*getter.HttpGetter); ok {
t.SetCredentials(r.Config.Username, r.Config.Password)
}
}
// Index generates an index for the chart repository and writes an index.yaml file.
func (r *ChartRepository) Index() error {
err := r.generateIndex()

@ -36,7 +36,7 @@ func ToYAML(s string) (string, error) {
return "", err
}
d, err := yaml.Marshal(m)
return strings.TrimSuffix(string(d), "\n"), err
return string(d), err
}
// Parse parses a set line.

@ -370,7 +370,7 @@ func TestToYAML(t *testing.T) {
if err != nil {
t.Fatal(err)
}
expect := "name: value"
expect := "name: value\n"
if o != expect {
t.Errorf("Expected %q, got %q", expect, o)
}

@ -12,15 +12,15 @@
# See the License for the specific language governing permissions and
# limitations under the License.
FROM alpine:3.3
FROM alpine:3.7
RUN apk update && apk add ca-certificates && rm -rf /var/cache/apk/*
ENV HOME /tmp
COPY tiller /tiller
COPY tiller /bin/tiller
EXPOSE 44134
CMD ["/tiller"]
USER nobody
ENTRYPOINT ["/bin/tiller"]

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

Loading…
Cancel
Save