Merge branch 'master' into readme-fix

pull/647/head
Ken Wronkiewicz 9 years ago
commit 3a7870b96f

1
.gitignore vendored

@ -1,6 +1,5 @@
.coverage/
bin/
rootfs/helm
rootfs/tiller
vendor/
_proto/*.pb.go

@ -4,8 +4,6 @@ SHORT_NAME ?= tiller
# go option
GO ?= go
GOARCH ?= $(shell go env GOARCH)
GOOS ?= $(shell go env GOOS)
PKG := $(shell glide novendor)
TAGS :=
TESTS := .
@ -30,11 +28,10 @@ check-docker:
fi
.PHONY: docker-binary
docker-binary: GOOS = linux
docker-binary: GOARCH = amd64
docker-binary: BINDIR = $(CURDIR)/rootfs
docker-binary: BINDIR = ./rootfs
docker-binary: GOFLAGS += -a -installsuffix cgo
docker-binary: build
docker-binary:
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 $(GO) build -o $(BINDIR)/tiller $(GOFLAGS) -tags '$(TAGS)' -ldflags '$(LDFLAGS)' github.com/kubernetes/helm/cmd/tiller
.PHONY: docker-build
docker-build: check-docker docker-binary
@ -58,13 +55,27 @@ test-style:
.PHONY: clean
clean:
@rm -rf $(BINDIR)
@rm ./rootfs/tiller
.PHONY: coverage
coverage:
@scripts/coverage.sh
HAS_GLIDE := $(shell command -v glide;)
HAS_HG := $(shell command -v hg;)
HAS_GIT := $(shell command -v git;)
.PHONY: bootstrap
bootstrap:
ifndef HAS_GLIDE
go get -u github.com/Masterminds/glide
endif
ifndef HAS_HG
$(error You must install Mercurial (hg))
endif
ifndef HAS_GIT
$(error You must install Git)
endif
glide install
include versioning.mk

@ -13,8 +13,13 @@ import (
"github.com/spf13/cobra"
)
var untarFile bool
var untarDir string
func init() {
RootCommand.AddCommand(fetchCmd)
fetchCmd.Flags().BoolVar(&untarFile, "untar", false, "If set to true, will untar the chart after downloading it.")
fetchCmd.Flags().StringVar(&untarDir, "untardir", ".", "If untar is specified, this flag specifies where to untar the chart.")
}
var fetchCmd = &cobra.Command{
@ -49,10 +54,8 @@ func fetch(cmd *cobra.Command, args []string) error {
}
defer resp.Body.Close()
// TODO(vaikas): Implement untar / flag
untar := false
if untar {
return untarChart(resp.Body)
if untarFile {
return chart.Expand(untarDir, resp.Body)
}
p := strings.Split(u.String(), "/")
return saveChartFile(p[len(p)-1], resp.Body)
@ -84,18 +87,6 @@ func mapRepoArg(arg string, r map[string]string) (*url.URL, error) {
return nil, fmt.Errorf("Invalid chart url format: %s", arg)
}
func untarChart(r io.Reader) error {
c, err := chart.LoadDataFromReader(r)
if err != nil {
return err
}
if c == nil {
return fmt.Errorf("Failed to untar the chart")
}
return fmt.Errorf("Not implemented yee")
}
func saveChartFile(c string, r io.Reader) error {
// Grab the chart name that we'll use for the name of the file to download to.
out, err := os.Create(c)

@ -39,7 +39,7 @@ func rmRelease(cmd *cobra.Command, args []string) error {
// TODO: Handle dry run use case.
if removeDryRun {
fmt.Printf("Deleting %s\n", args[0])
fmt.Printf("DRY RUN: Deleting %s\n", args[0])
return nil
}

@ -128,11 +128,15 @@ type KubeClient interface {
//
// reader must contain a YAML stream (one or more YAML documents separated
// by "\n---\n").
//
// config is optional. If nil, the client will use its existing configuration.
// If set, the client will override its default configuration with the
// passed in one.
Create(namespace string, reader io.Reader) error
// Delete destroys one or more resources.
//
// namespace must contain a valid existing namespace.
//
// reader must contain a YAML stream (one or more YAML documents separated
// by "\n---\n").
Delete(namespace string, reader io.Reader) error
}
// PrintingKubeClient implements KubeClient, but simply prints the reader to
@ -146,6 +150,10 @@ func (p *PrintingKubeClient) Create(ns string, r io.Reader) error {
_, err := io.Copy(p.Out, r)
return err
}
func (p *PrintingKubeClient) Delete(ns string, r io.Reader) error {
_, err := io.Copy(p.Out, r)
return err
}
// Environment provides the context for executing a client request.
//

@ -53,6 +53,9 @@ type mockKubeClient struct {
func (k *mockKubeClient) Create(ns string, r io.Reader) error {
return nil
}
func (k *mockKubeClient) Delete(ns string, r io.Reader) error {
return nil
}
var _ Engine = &mockEngine{}
var _ ReleaseStorage = &mockReleaseStorage{}

@ -207,8 +207,12 @@ func (s *releaseServer) UninstallRelease(c ctx.Context, req *services.UninstallR
rel.Info.Status.Code = release.Status_DELETED
rel.Info.Deleted = timeconv.Now()
// TODO: Once KubeClient is ready, delete the resources.
log.Println("WARNING: Currently not deleting resources from k8s")
b := bytes.NewBuffer([]byte(rel.Manifest))
if err := s.env.KubeClient.Delete(s.env.Namespace, b); err != nil {
log.Printf("uninstall: Failed deletion of %q: %s", req.Name, err)
return nil, err
}
if err := s.env.Releases.Update(rel); err != nil {
log.Printf("uninstall: Failed to store updated release: %s", err)

@ -5,9 +5,9 @@ metadata:
labels:
heritage: {{.Release.Service}}
chartName: {{.Chart.Name}}
chartVersion: {{.Chart.Version}}
chartVersion: {{.Chart.Version | quote}}
annotations:
"helm.sh/created": {{.Release.Time.Seconds}}
"helm.sh/created": "{{.Release.Time.Seconds}}"
spec:
restartPolicy: {{default "Never" .restart_policy}}
containers:

@ -88,7 +88,7 @@ func (c *Chart) TemplatesDir() string {
return filepath.Join(c.loader.dir(), preTemplates)
}
// ChartsDir returns teh directory where dependency charts are stored.
// ChartsDir returns the directory where dependency charts are stored.
func (c *Chart) ChartsDir() string {
return filepath.Join(c.loader.dir(), preCharts)
}
@ -214,6 +214,44 @@ func Create(chartfile *Chartfile, dir string) (*Chart, error) {
}, nil
}
// Expand uncompresses and extracts a chart into the specified directory.
func Expand(dir string, r io.Reader) error {
gr, err := gzip.NewReader(r)
if err != nil {
return err
}
defer gr.Close()
tr := tar.NewReader(gr)
for {
header, err := tr.Next()
if err == io.EOF {
break
} else if err != nil {
return err
}
path := filepath.Clean(filepath.Join(dir, header.Name))
info := header.FileInfo()
if info.IsDir() {
if err = os.MkdirAll(path, info.Mode()); err != nil {
return err
}
continue
}
file, err := os.OpenFile(path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, info.Mode())
if err != nil {
return err
}
defer file.Close()
_, err = io.Copy(file, tr)
if err != nil {
return err
}
}
return nil
}
// fname prepares names for the filesystem
func fname(name string) string {
// Right now, we don't do anything. Do we need to encode any particular

@ -30,6 +30,7 @@ const (
testdir = "testdata/frobnitz/"
testarchive = "testdata/frobnitz-0.0.1.tgz"
testmember = "templates/template.tpl"
expectedTemplate = "Hello {{.Name | default \"world\"}}\n"
)
// Type canaries. If these fail, they will fail at compile time.
@ -270,3 +271,42 @@ func compareContent(filename string, content []byte) error {
return nil
}
func TestExpand(t *testing.T) {
r, err := os.Open(testarchive)
if err != nil {
t.Errorf("Failed to read testarchive file: %s", err)
return
}
td, err := ioutil.TempDir("", "helm-unittest-chart-")
if err != nil {
t.Errorf("Failed to create tempdir: %s", err)
return
}
err = Expand(td, r)
if err != nil {
t.Errorf("Failed to expand testarchive file: %s", err)
}
fi, err := os.Lstat(td + "/frobnitz/Chart.yaml")
if err != nil {
t.Errorf("Failed to stat Chart.yaml from expanded archive: %s", err)
}
if fi.Name() != "Chart.yaml" {
t.Errorf("Didn't get the right file name from stat, expected Chart.yaml, got: %s", fi.Name())
}
tr, err := os.Open(td + "/frobnitz/templates/template.tpl")
if err != nil {
t.Errorf("Failed to open template.tpl from expanded archive: %s", err)
}
c, err := ioutil.ReadAll(tr)
if err != nil {
t.Errorf("Failed to read contents of template.tpl from expanded archive: %s", err)
}
if string(c) != expectedTemplate {
t.Errorf("Contents of the expanded template differ, wanted '%s' got '%s'", expectedTemplate, c)
}
}

@ -32,6 +32,14 @@ func (c *Client) Create(namespace string, reader io.Reader) error {
return perform(f, namespace, reader, createResource)
}
// Delete deletes kubernetes resources from an io.reader
//
// Namespace will set the namespace
func (c *Client) Delete(namespace string, reader io.Reader) error {
f := cmdutil.NewFactory(c.config)
return perform(f, namespace, reader, deleteResource)
}
const includeThirdPartyAPIs = false
func perform(f *cmdutil.Factory, namespace string, reader io.Reader, fn ResourceActorFunc) error {
@ -73,3 +81,7 @@ func createResource(info *resource.Info) error {
_, err := resource.NewHelper(info.Client, info.Mapping).Create(info.Namespace, true, info.Object)
return err
}
func deleteResource(info *resource.Info) error {
return resource.NewHelper(info.Client, info.Mapping).Delete(info.Namespace, info.Name)
}

@ -65,6 +65,17 @@ func TestPerform(t *testing.T) {
}
}
func TestReal(t *testing.T) {
t.Skip("This is a live test, comment this line to run")
if err := New(nil).Create("test", strings.NewReader(guestbookManifest)); err != nil {
t.Fatal(err)
}
if err := New(nil).Delete("test", strings.NewReader(guestbookManifest)); err != nil {
t.Fatal(err)
}
}
const guestbookManifest = `
apiVersion: v1
kind: Service

@ -30,6 +30,18 @@ command_exists() {
hash "${1}" 2>/dev/null
}
# fetch url using wget or curl and print to stdout
fetch_url() {
local url="$1"
if command_exists wget; then
curl -sSL "$url"
elif command_exists curl; then
wget -qO- "$url"
else
error_exit "Couldn't find curl or wget. Bailing out."
fi
}
# Program Functions ------------------------------------------------------------
# Check host platform and docker host
@ -78,28 +90,30 @@ verify_prereqs() {
command_exists docker || error_exit "You need docker"
if ! docker info > /dev/null 2>&1 ; then
if ! docker info >/dev/null 2>&1 ; then
error_exit "Can't connect to 'docker' daemon."
fi
if docker inspect kubelet >/dev/null 2>&1 ; then
error_exit "Kubernetes is already running"
fi
$KUBECTL version --client >/dev/null || download_kubectl
}
# Get the latest stable release tag
get_latest_version_number() {
local -r latest_url="https://storage.googleapis.com/kubernetes-release/release/stable.txt"
if command_exists wget ; then
wget -qO- ${latest_url}
elif command_exists curl ; then
curl -Ss ${latest_url}
else
error_exit "Couldn't find curl or wget. Bailing out."
local channel="stable"
if [[ -n "${ALPHA:-}" ]]; then
channel="latest"
fi
local latest_url="https://storage.googleapis.com/kubernetes-release/release/${channel}.txt"
fetch_url "$latest_url"
}
# Detect ip address od docker host
detect_docker_host_ip() {
if [ -n "${DOCKER_HOST:-}" ]; then
if [[ -n "${DOCKER_HOST:-}" ]]; then
awk -F'[/:]' '{print $4}' <<< "$DOCKER_HOST"
else
ifconfig docker0 \
@ -151,27 +165,33 @@ start_kubernetes() {
/hyperkube kubelet \
--containerized \
--hostname-override="127.0.0.1" \
--api-servers=http://localhost:8080 \
--api-servers=http://localhost:${KUBE_PORT} \
--config=/etc/kubernetes/manifests \
--allow-privileged=true \
${dns_args} \
--v=${LOG_LEVEL} >/dev/null
until $KUBECTL cluster-info &> /dev/null; do
sleep 1
done
# Create kube-system namespace in kubernetes
$KUBECTL create namespace kube-system >/dev/null
# We expect to have at least 3 running pods - etcd, master and kube-proxy.
local attempt=1
while (($($KUBECTL get pods --no-headers 2>/dev/null | grep -c "Running") < 3)); do
while (($(KUBECTL get pods --all-namespaces --no-headers 2>/dev/null | grep -c "Running") < 3)); do
echo -n "."
sleep $(( attempt++ ))
done
echo
local end_time=$(date +%s)
echo "Started master components in $((end_time - start_time)) seconds."
echo "Started master components in $(($(date +%s) - start_time)) seconds."
}
# Open kubernetes master api port.
setup_firewall() {
[[ -n "${DOCKER_MACHINE_NAME}" ]] || return
[[ -n "${DOCKER_MACHINE_NAME:-}" ]] || return
echo "Adding iptables hackery for docker-machine..."
@ -184,13 +204,6 @@ setup_firewall() {
fi
}
# Create kube-system namespace in kubernetes
create_kube_system_namespace() {
echo "Creating kube-system namespace..."
$KUBECTL create -f ./scripts/cluster/kube-system.yaml >/dev/null
}
# Activate skydns in kubernetes and wait for pods to be ready.
create_kube_dns() {
[[ "${ENABLE_CLUSTER_DNS}" = true ]] || return
@ -209,8 +222,7 @@ create_kube_dns() {
sleep $(( attempt++ ))
done
echo
local end_time=$(date +%s)
echo "Started DNS in $((end_time - start_time)) seconds."
echo "Started DNS in $(($(date +%s) - start_time)) seconds."
}
# Generate kubeconfig data for the created cluster.
@ -231,17 +243,13 @@ generate_kubeconfig() {
download_kubectl() {
echo "Downloading kubectl binary..."
local output="/usr/local/bin/kubectl"
kubectl_url="https://storage.googleapis.com/kubernetes-release/release/${KUBE_VERSION}/bin/${host_os}/${host_arch}/kubectl"
if command_exists wget; then
wget -O ./bin/kubectl "${kubectl_url}"
elif command_exists curl; then
curl -sSOL ./bin/kubectl "${kubectl_url}"
else
error_exit "Couldn't find curl or wget. Bailing out."
fi
chmod a+x ./bin/kubectl
fetch_url "${kubectl_url}" > "${output}"
chmod a+x "${output}"
KUBECTL=./bin/kubectl
KUBECTL="${output}"
}
# Clean volumes that are left by kubelet
@ -297,9 +305,8 @@ kube_up() {
clean_volumes
setup_firewall
start_kubernetes
generate_kubeconfig
create_kube_system_namespace
start_kubernetes
create_kube_dns
$KUBECTL cluster-info

Loading…
Cancel
Save