From 4120e67240afdacb6b2f91540d575216470532bb Mon Sep 17 00:00:00 2001 From: Vic Iglesias Date: Tue, 25 Oct 2016 16:56:51 -0700 Subject: [PATCH 1/6] Add deployment, service and NOTES to create --- pkg/chartutil/create.go | 118 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 116 insertions(+), 2 deletions(-) diff --git a/pkg/chartutil/create.go b/pkg/chartutil/create.go index 8d0990e06..40d46bb2c 100644 --- a/pkg/chartutil/create.go +++ b/pkg/chartutil/create.go @@ -36,12 +36,29 @@ const ( ChartsDir = "charts" // IgnorefileName is the name of the Helm ignore file. IgnorefileName = ".helmignore" + // DeploymentName is the name of the example deployment file. + DeploymentName = "deployment.yaml" + // ServiceName is the name of the example service file. + ServiceName = "service.yaml" + // NotesName is the name of the example NOTES.txt file. + NotesName = "NOTES.txt" + // HelpersName is the name of the example NOTES.txt file. + HelpersName = "_helpers.tpl" ) const defaultValues = `# Default values for %s. # This is a YAML-formatted file. -# Declare name/value pairs to be passed into your templates. -# name: value +# Declare variables to be passed into your templates. +replicaCount: 1 +image: + repository: nginx + tag: stable + pullPolicy: IfNotPresent +service: + name: nginx + type: ClusterIP + externalPort: 80 + internalPort: 80 ` const defaultIgnore = `# Patterns to ignore when building packages. @@ -67,6 +84,79 @@ const defaultIgnore = `# Patterns to ignore when building packages. *.tmproj ` +const defaultDeployment = `apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: {{ template "fullname" . }} + labels: + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" +spec: + replicas: {{ .Values.replicaCount }} + template: + metadata: + labels: + app: {{ template "fullname" . }} + spec: + containers: + - name: nginx + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - containerPort: {{ .Values.service.internalPort }} +` + +const defaultService = `apiVersion: v1 +kind: Service +metadata: + name: {{ template "fullname" . }} + labels: + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.externalPort }} + targetPort: {{ .Values.service.internalPort }} + protocol: TCP + name: {{ .Values.service.name }} + selector: + app: {{ template "fullname" . }} +` + +const defaultNotes = `1. Get the application URL by running these commands: +{{- if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT/login +{{- else if contains "LoadBalancer" .Values.service.type }} +**** NOTE: It may take a few minutes for the LoadBalancer IP to be available. **** +**** You can watch the status of by running 'kubectl get svc -w {{ template "fullname" . }}' **** + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') + echo http://$SERVICE_IP:{{ .Values.Master.ServicePort }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "component={{ template "fullname" . }}-master" -o jsonpath="{.items[0].metadata.name}") + echo http://127.0.0.1:{{ .Values.service.externalPort }} + kubectl port-forward $POD_NAME {{ .Values.service.externalPort }}:{{ .Values.service.externalPort }} +{{- end }} +` + +const defaultHelpers = `{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 24 -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 24 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "fullname" -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- printf "%s-%s" .Release.Name $name | trunc 24 -}} +{{- end -}} +` + // Create creates a new chart in a directory. // // Inside of dir, this will create a directory based on the name of @@ -120,5 +210,29 @@ func Create(chartfile *chart.Metadata, dir string) (string, error) { return cdir, err } } + + // Write out deployment.yaml + val = []byte(defaultDeployment) + if err := ioutil.WriteFile(filepath.Join(cdir, TemplatesDir, DeploymentName), val, 0644); err != nil { + return cdir, err + } + + // Write out service.yaml + val = []byte(defaultService) + if err := ioutil.WriteFile(filepath.Join(cdir, TemplatesDir, ServiceName), val, 0644); err != nil { + return cdir, err + } + + // Write out NOTES.txt + val = []byte(defaultNotes) + if err := ioutil.WriteFile(filepath.Join(cdir, TemplatesDir, NotesName), val, 0644); err != nil { + return cdir, err + } + + // Write out _helpers.tpl + val = []byte(defaultHelpers) + if err := ioutil.WriteFile(filepath.Join(cdir, TemplatesDir, HelpersName), val, 0644); err != nil { + return cdir, err + } return cdir, nil } From 8d867657bb452a55d9c29439dd4e943bd5b4e8dc Mon Sep 17 00:00:00 2001 From: Vic Iglesias Date: Tue, 25 Oct 2016 17:45:08 -0700 Subject: [PATCH 2/6] Add resources and probes --- pkg/chartutil/create.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pkg/chartutil/create.go b/pkg/chartutil/create.go index 40d46bb2c..c413f27cc 100644 --- a/pkg/chartutil/create.go +++ b/pkg/chartutil/create.go @@ -59,6 +59,14 @@ service: type: ClusterIP externalPort: 80 internalPort: 80 +resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 100m + memory: 128Mi + ` const defaultIgnore = `# Patterns to ignore when building packages. @@ -103,6 +111,16 @@ spec: imagePullPolicy: {{ .Values.image.pullPolicy }} ports: - containerPort: {{ .Values.service.internalPort }} + livenessProbe: + httpGet: + path: / + port: 80 + readinessProbe: + httpGet: + path: / + port: 80 + resources: +{{ toYaml .Values.resources | indent 12 }} ` const defaultService = `apiVersion: v1 From cd34492b5a0599eaee14e68a6cb51e777fa1ea3f Mon Sep 17 00:00:00 2001 From: Vic Iglesias Date: Tue, 25 Oct 2016 17:48:49 -0700 Subject: [PATCH 3/6] Add tests for new files in create --- pkg/chartutil/create_test.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/pkg/chartutil/create_test.go b/pkg/chartutil/create_test.go index e2dc0b4ff..19c2e041e 100644 --- a/pkg/chartutil/create_test.go +++ b/pkg/chartutil/create_test.go @@ -62,7 +62,15 @@ func TestCreate(t *testing.T) { if fi, err := os.Stat(filepath.Join(dir, f)); err != nil { t.Errorf("Expected %s file: %s", f, err) } else if fi.IsDir() { - t.Errorf("Expected %s to be a fle.", f) + t.Errorf("Expected %s to be a file.", f) + } + } + + for _, f := range []string{NotesName, DeploymentName, ServiceName, HelpersName} { + if fi, err := os.Stat(filepath.Join(dir, TemplatesDir, f)); err != nil { + t.Errorf("Expected %s file: %s", f, err) + } else if fi.IsDir() { + t.Errorf("Expected %s to be a file.", f) } } From 06d9ccd03816e75518b9080a07c672a41846c492 Mon Sep 17 00:00:00 2001 From: Vic Iglesias Date: Tue, 25 Oct 2016 17:52:16 -0700 Subject: [PATCH 4/6] Fix formatting --- pkg/chartutil/create.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/chartutil/create.go b/pkg/chartutil/create.go index c413f27cc..3ff1e1406 100644 --- a/pkg/chartutil/create.go +++ b/pkg/chartutil/create.go @@ -232,25 +232,25 @@ func Create(chartfile *chart.Metadata, dir string) (string, error) { // Write out deployment.yaml val = []byte(defaultDeployment) if err := ioutil.WriteFile(filepath.Join(cdir, TemplatesDir, DeploymentName), val, 0644); err != nil { - return cdir, err + return cdir, err } // Write out service.yaml val = []byte(defaultService) if err := ioutil.WriteFile(filepath.Join(cdir, TemplatesDir, ServiceName), val, 0644); err != nil { - return cdir, err + return cdir, err } // Write out NOTES.txt val = []byte(defaultNotes) if err := ioutil.WriteFile(filepath.Join(cdir, TemplatesDir, NotesName), val, 0644); err != nil { - return cdir, err + return cdir, err } // Write out _helpers.tpl val = []byte(defaultHelpers) if err := ioutil.WriteFile(filepath.Join(cdir, TemplatesDir, HelpersName), val, 0644); err != nil { - return cdir, err + return cdir, err } return cdir, nil } From 2b2e1d59c82ae7df9d4a7ca2a32583d88eace87a Mon Sep 17 00:00:00 2001 From: Vic Iglesias Date: Wed, 26 Oct 2016 09:32:40 -0700 Subject: [PATCH 5/6] Simplify final logic block in create --- pkg/chartutil/create.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pkg/chartutil/create.go b/pkg/chartutil/create.go index 3ff1e1406..954dc502f 100644 --- a/pkg/chartutil/create.go +++ b/pkg/chartutil/create.go @@ -249,8 +249,5 @@ func Create(chartfile *chart.Metadata, dir string) (string, error) { // Write out _helpers.tpl val = []byte(defaultHelpers) - if err := ioutil.WriteFile(filepath.Join(cdir, TemplatesDir, HelpersName), val, 0644); err != nil { - return cdir, err - } - return cdir, nil + return cdir, ioutil.WriteFile(filepath.Join(cdir, TemplatesDir, HelpersName), val, 0644) } From 665615f30f8c06080d172f499fedd42a79408c99 Mon Sep 17 00:00:00 2001 From: Vic Iglesias Date: Wed, 26 Oct 2016 09:34:11 -0700 Subject: [PATCH 6/6] Remove **** from default notes --- pkg/chartutil/create.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/chartutil/create.go b/pkg/chartutil/create.go index 954dc502f..74556a788 100644 --- a/pkg/chartutil/create.go +++ b/pkg/chartutil/create.go @@ -146,8 +146,8 @@ const defaultNotes = `1. Get the application URL by running these commands: export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") echo http://$NODE_IP:$NODE_PORT/login {{- else if contains "LoadBalancer" .Values.service.type }} -**** NOTE: It may take a few minutes for the LoadBalancer IP to be available. **** -**** You can watch the status of by running 'kubectl get svc -w {{ template "fullname" . }}' **** + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get svc -w {{ template "fullname" . }}' export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') echo http://$SERVICE_IP:{{ .Values.Master.ServicePort }} {{- else if contains "ClusterIP" .Values.service.type }}