diff --git a/.gitignore b/.gitignore index 1a3ab219d..875c22e57 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,10 @@ -expandybird/pkg/* -expandybird/expansion/*.pyc -resourcifier/pkg/* -resourcifier/bin/* -manager/pkg/* +*.pyc .project -vendor/* +/bin +/vendor/* +/rootfs/manager/bin/manager +/rootfs/manager/bin/kubectl +/rootfs/resourcifier/bin/resourcifier +/rootfs/resourcifier/bin/kubectl +/rootfs/expandybird/bin/expandybird +/rootfs/expandybird/opt/expansion diff --git a/.travis.yml b/.travis.yml index 69baae606..c63fac3fb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,24 @@ sudo: true +env: + - GO15VENDOREXPERIMENT=1 GLIDE_VERSION="0.9.1" + language: go go: - - 1.4 - -install: - - sudo pip install -r expandybird/requirements.txt + - 1.6 script: - - make setup-gotools test + - make bootstrap test + +branches: + only: + - master + - /^v?(?:[0-9]+\.){2}[0-9]+.*$/ + +install: + - wget "https://github.com/Masterminds/glide/releases/download/$GLIDE_VERSION/glide-$GLIDE_VERSION-linux-amd64.tar.gz" + - mkdir -p $HOME/bin + - tar -vxz -C $HOME/bin --strip=1 -f glide-$GLIDE_VERSION-linux-amd64.tar.gz + - export PATH="$HOME/bin:$PATH" GLIDE_HOME="$HOME/.glide" + - sudo pip install -r expansion/requirements.txt diff --git a/Makefile b/Makefile index 507ad93a2..bb052f0df 100644 --- a/Makefile +++ b/Makefile @@ -12,41 +12,80 @@ # See the License for the specific language governing permissions and # limitations under the License. -include include.mk - -SUBDIRS := expandybird/. resourcifier/. manager/. -TARGETS := all build test push container clean - -SUBDIRS_TARGETS := \ - $(foreach t,$(TARGETS),$(addsuffix $t,$(SUBDIRS))) +ifndef GOPATH +$(error No GOPATH set) +endif -GO_DEPS := github.com/kubernetes/deployment-manager/util/... github.com/kubernetes/deployment-manager/version/... github.com/kubernetes/deployment-manager/expandybird/... github.com/kubernetes/deployment-manager/resourcifier/... github.com/kubernetes/deployment-manager/manager/... github.com/kubernetes/deployment-manager/dm/... +include include.mk -.PHONY : all build test clean $(TARGETS) $(SUBDIRS_TARGETS) .project .docker +GO_DIRS ?= $(shell glide nv -x ) +GO_PKGS ?= $(shell glide nv) +.PHONY: build build: - go get -v $(GO_DEPS) - go install -v $(GO_DEPS) + @scripts/build-go.sh + +.PHONY: build-cross +build-cross: + @BUILD_CROSS=1 scripts/build-go.sh +.PHONY: all all: build +.PHONY: clean clean: - go clean -v $(GO_DEPS) + go clean -v $(GO_PKGS) + rm -rf bin -test: build - go test -v $(GO_DEPS) +.PHONY: test +test: build test-style test-unit +.PHONY: push push: container +.PHONY: container container: .project .docker +.PHONY: test-unit +test-unit: + @echo Running tests... + go test -v $(GO_PKGS) + +.PHONY: .test-style +test-style: lint vet + @if [[ -z $(shell gofmt -e -l -s $(GO_DIRS) | wc -l) ]]; then \ + echo "gofmt check failed:"; gofmt -e -d -s $(GO_DIRS); exit 1; \ + fi + +.PHONY: lint +lint: + @echo Running golint... + @for i in $(GO_PKGS); do \ + golint $$i; \ + done + @echo ----------------- + +.PHONY: vet +vet: + @echo Running go vet... + @for i in $(GO_DIRS); do \ + go tool vet $$i; \ + done + @echo ----------------- + +.PHONY: bootstrap +bootstrap: + @echo Installing deps + go get -u github.com/golang/lint/golint + go get -u golang.org/x/tools/cmd/vet + go get -u github.com/mitchellh/gox + glide install + +.PHONY: .project .project: @if [[ -z "${PROJECT}" ]]; then echo "PROJECT variable must be set"; exit 1; fi +.PHONY: .docker .docker: @if [[ -z `which docker` ]] || ! docker version &> /dev/null; then echo "docker is not installed correctly"; exit 1; fi -$(TARGETS) : % : $(addsuffix %,$(SUBDIRS)) - -$(SUBDIRS_TARGETS) : - $(MAKE) -C $(@D) $(@F:.%=%) diff --git a/dm/Dockerfile b/cmd/dm/Dockerfile similarity index 100% rename from dm/Dockerfile rename to cmd/dm/Dockerfile diff --git a/dm/Makefile b/cmd/dm/Makefile similarity index 74% rename from dm/Makefile rename to cmd/dm/Makefile index aa771203b..7ae51e886 100644 --- a/dm/Makefile +++ b/cmd/dm/Makefile @@ -14,7 +14,7 @@ SHELL := /bin/bash -GOLANG_CROSSPLATFORMS := darwin/386 darwin/amd64 freebsd/386 freebsd/amd64 freebsd/arm linux/386 linux/amd64 linux/arm windows/386 windows/amd64 +GOLANG_CROSSPLATFORMS="darwin/386 darwin/amd64 freebsd/386 freebsd/amd64 freebsd/arm linux/386 linux/amd64 linux/arm windows/386 windows/amd64" all: build binary @@ -22,15 +22,13 @@ build: docker build -t dm . binary: - - docker stop dm - - docker rm dm docker run --name dm dm - for platform in ${GOLANG_CROSSPLATFORMS}; do \ + for platform in $$GOLANG_CROSSPLATFORMS; do \ echo $$platform; \ docker cp dm:/go/src/dm/dm-$${platform%/*}-$${platform##*/} .; \ done clean: - - docker rm dm - - docker rmi dm - rm -f dm-* + docker rm dm + docker rmi dm + rm dm-* diff --git a/dm/dm.go b/cmd/dm/dm.go similarity index 98% rename from dm/dm.go rename to cmd/dm/dm.go index b348605fd..9e33bf5a9 100644 --- a/dm/dm.go +++ b/cmd/dm/dm.go @@ -19,8 +19,8 @@ package main import ( "github.com/ghodss/yaml" - "github.com/kubernetes/deployment-manager/common" - "github.com/kubernetes/deployment-manager/util" + "github.com/kubernetes/deployment-manager/pkg/common" + "github.com/kubernetes/deployment-manager/pkg/util" "archive/tar" "bytes" @@ -272,7 +272,7 @@ func callService(path, method, action string, reader io.ReadCloser) { var URL *url.URL URL, err := url.Parse(*service) if err != nil { - panic(fmt.Errorf("cannot parse url (%s): %s\n", *service, err)) + panic(fmt.Errorf("cannot parse url (%s): %s\n", path, err)) } URL.Path = strings.TrimRight(URL.Path, "/") + "/" + strings.TrimLeft(path, "/") diff --git a/cmd/doc.go b/cmd/doc.go new file mode 100644 index 000000000..91b7ead51 --- /dev/null +++ b/cmd/doc.go @@ -0,0 +1,2 @@ +// Package cmd contains the executables for Deployment Manager. +package cmd diff --git a/expandybird/Dockerfile b/cmd/expandybird/Dockerfile similarity index 100% rename from expandybird/Dockerfile rename to cmd/expandybird/Dockerfile diff --git a/expandybird/Makefile b/cmd/expandybird/Makefile similarity index 98% rename from expandybird/Makefile rename to cmd/expandybird/Makefile index 16f0c7882..df97481fd 100644 --- a/expandybird/Makefile +++ b/cmd/expandybird/Makefile @@ -19,6 +19,7 @@ include ../include.mk DOCKER_REGISTRY := gcr.io PREFIX := $(DOCKER_REGISTRY)/$(PROJECT) IMAGE := expandybird +TAG := latest ROOT_DIR := $(abspath ./..) DIR = $(ROOT_DIR) diff --git a/expandybird/expander/expander.go b/cmd/expandybird/expander/expander.go similarity index 98% rename from expandybird/expander/expander.go rename to cmd/expandybird/expander/expander.go index 01176301f..f8d5472ca 100644 --- a/expandybird/expander/expander.go +++ b/cmd/expandybird/expander/expander.go @@ -24,7 +24,7 @@ import ( "os/exec" "github.com/ghodss/yaml" - "github.com/kubernetes/deployment-manager/common" + "github.com/kubernetes/deployment-manager/pkg/common" ) // Expander abstracts interactions with the expander and deployer services. diff --git a/expandybird/expander/expander_test.go b/cmd/expandybird/expander/expander_test.go similarity index 96% rename from expandybird/expander/expander_test.go rename to cmd/expandybird/expander/expander_test.go index bb12577c1..efde69559 100644 --- a/expandybird/expander/expander_test.go +++ b/cmd/expandybird/expander/expander_test.go @@ -26,8 +26,8 @@ import ( "strings" "testing" - "github.com/kubernetes/deployment-manager/common" - "github.com/kubernetes/deployment-manager/util" + "github.com/kubernetes/deployment-manager/pkg/common" + "github.com/kubernetes/deployment-manager/pkg/util" ) var importFileNames = []string{ @@ -37,7 +37,7 @@ var importFileNames = []string{ var validFileName = "../test/ValidContent.yaml" var outputFileName = "../test/ExpectedOutput.yaml" var archiveFileName = "../test/TestArchive.tar" -var expanderName = "../expansion/expansion.py" +var expanderName = "../../../expansion/expansion.py" type ExpanderTestCase struct { Description string diff --git a/expandybird/main.go b/cmd/expandybird/main.go similarity index 82% rename from expandybird/main.go rename to cmd/expandybird/main.go index df2d3714e..332ffa33d 100644 --- a/expandybird/main.go +++ b/cmd/expandybird/main.go @@ -6,7 +6,7 @@ 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. @@ -17,9 +17,9 @@ limitations under the License. package main import ( - "github.com/kubernetes/deployment-manager/expandybird/expander" - "github.com/kubernetes/deployment-manager/expandybird/service" - "github.com/kubernetes/deployment-manager/version" + "github.com/kubernetes/deployment-manager/cmd/expandybird/expander" + "github.com/kubernetes/deployment-manager/cmd/expandybird/service" + "github.com/kubernetes/deployment-manager/pkg/version" "flag" "fmt" @@ -33,7 +33,7 @@ import ( var port = flag.Int("port", 8080, "Port to listen on") // path to expansion binary -var expansionBinary = flag.String("expansion_binary", "../expansion/expansion.py", +var expansionBinary = flag.String("expansion_binary", "../../../expansion/expansion.py", "The path to the expansion binary that will be used to expand the template.") func main() { diff --git a/expandybird/service/service.go b/cmd/expandybird/service/service.go similarity index 94% rename from expandybird/service/service.go rename to cmd/expandybird/service/service.go index ac75d47e6..e12fdda8a 100644 --- a/expandybird/service/service.go +++ b/cmd/expandybird/service/service.go @@ -17,9 +17,9 @@ limitations under the License. package service import ( - "github.com/kubernetes/deployment-manager/common" - "github.com/kubernetes/deployment-manager/expandybird/expander" - "github.com/kubernetes/deployment-manager/util" + "github.com/kubernetes/deployment-manager/cmd/expandybird/expander" + "github.com/kubernetes/deployment-manager/pkg/common" + "github.com/kubernetes/deployment-manager/pkg/util" "errors" "fmt" @@ -86,7 +86,7 @@ func NewExpansionHandler(backend expander.Expander) restful.RouteFunction { } util.LogHandlerExit("expandybird", http.StatusOK, "OK", resp.ResponseWriter) - message := fmt.Sprintf("\nConfig:\n%s\nLayout:\n%s\n", response.Config, response.Layout) + message := fmt.Sprintf("\nConfig:\n%s\nLayout:\n%s\n", response.Config, response.Layout) util.LogHandlerText("expandybird", message) resp.WriteEntity(response) } diff --git a/expandybird/service/service_test.go b/cmd/expandybird/service/service_test.go similarity index 96% rename from expandybird/service/service_test.go rename to cmd/expandybird/service/service_test.go index ee5f029ae..1af7a4d35 100644 --- a/expandybird/service/service_test.go +++ b/cmd/expandybird/service/service_test.go @@ -26,9 +26,9 @@ import ( "reflect" "testing" - "github.com/kubernetes/deployment-manager/common" - "github.com/kubernetes/deployment-manager/expandybird/expander" - "github.com/kubernetes/deployment-manager/util" + "github.com/kubernetes/deployment-manager/cmd/expandybird/expander" + "github.com/kubernetes/deployment-manager/pkg/common" + "github.com/kubernetes/deployment-manager/pkg/util" restful "github.com/emicklei/go-restful" ) @@ -112,7 +112,7 @@ var ServiceWrapperTestCases = []ServiceWrapperTestCase{ } func TestServiceWrapper(t *testing.T) { - backend := expander.NewExpander("../expansion/expansion.py") + backend := expander.NewExpander("../../../expansion/expansion.py") wrapper := NewService(NewExpansionHandler(backend)) container := restful.NewContainer() container.ServeMux = http.NewServeMux() diff --git a/expandybird/test/ExpectedOutput.yaml b/cmd/expandybird/test/ExpectedOutput.yaml similarity index 94% rename from expandybird/test/ExpectedOutput.yaml rename to cmd/expandybird/test/ExpectedOutput.yaml index 13e510d3c..24bd519a3 100644 --- a/expandybird/test/ExpectedOutput.yaml +++ b/cmd/expandybird/test/ExpectedOutput.yaml @@ -51,7 +51,7 @@ config: spec: containers: - env: [] - image: gcr.io/dm-k8s-prod/expandybird + image: gcr.io/dm-k8s-testing/expandybird name: expandybird ports: - containerPort: 8080 @@ -63,7 +63,7 @@ layout: properties: container_port: 8080 external_service: true - image: gcr.io/dm-k8s-prod/expandybird + image: gcr.io/dm-k8s-testing/expandybird labels: app: expandybird replicas: 3 diff --git a/expandybird/test/InvalidFileName.yaml b/cmd/expandybird/test/InvalidFileName.yaml similarity index 95% rename from expandybird/test/InvalidFileName.yaml rename to cmd/expandybird/test/InvalidFileName.yaml index fd3800466..712426be2 100644 --- a/expandybird/test/InvalidFileName.yaml +++ b/cmd/expandybird/test/InvalidFileName.yaml @@ -19,4 +19,4 @@ resources: properties: service_port: 8080 target_port: 8080 - image: gcr.io/dm-k8s-prod/expandybird + image: gcr.io/dm-k8s-testing/expandybird diff --git a/expandybird/test/InvalidProperty.yaml b/cmd/expandybird/test/InvalidProperty.yaml similarity index 94% rename from expandybird/test/InvalidProperty.yaml rename to cmd/expandybird/test/InvalidProperty.yaml index fd3d5edeb..7eeb78538 100644 --- a/expandybird/test/InvalidProperty.yaml +++ b/cmd/expandybird/test/InvalidProperty.yaml @@ -19,4 +19,4 @@ resources: properties: service_port: 8080 target_port: 8080 - invalidproperty: gcr.io/dm-k8s-prod/expandybird + invalidproperty: gcr.io/dm-k8s-testing/expandybird diff --git a/expandybird/test/InvalidTypeName.yaml b/cmd/expandybird/test/InvalidTypeName.yaml similarity index 95% rename from expandybird/test/InvalidTypeName.yaml rename to cmd/expandybird/test/InvalidTypeName.yaml index e411c1b11..387e4a172 100644 --- a/expandybird/test/InvalidTypeName.yaml +++ b/cmd/expandybird/test/InvalidTypeName.yaml @@ -19,4 +19,4 @@ resources: properties: service_port: 8080 target_port: 8080 - image: gcr.io/dm-k8s-prod/expandybird + image: gcr.io/dm-k8s-testing/expandybird diff --git a/expandybird/test/MalformedContent.yaml b/cmd/expandybird/test/MalformedContent.yaml similarity index 100% rename from expandybird/test/MalformedContent.yaml rename to cmd/expandybird/test/MalformedContent.yaml diff --git a/expandybird/test/MissingImports.yaml b/cmd/expandybird/test/MissingImports.yaml similarity index 95% rename from expandybird/test/MissingImports.yaml rename to cmd/expandybird/test/MissingImports.yaml index 6a6741f8a..e6a24e6f6 100644 --- a/expandybird/test/MissingImports.yaml +++ b/cmd/expandybird/test/MissingImports.yaml @@ -18,4 +18,4 @@ resources: properties: service_port: 8080 target_port: 8080 - image: gcr.io/dm-k8s-prod/expandybird + image: gcr.io/dm-k8s-testing/expandybird diff --git a/expandybird/test/MissingResourceName.yaml b/cmd/expandybird/test/MissingResourceName.yaml similarity index 95% rename from expandybird/test/MissingResourceName.yaml rename to cmd/expandybird/test/MissingResourceName.yaml index 32215e765..8ae93dace 100644 --- a/expandybird/test/MissingResourceName.yaml +++ b/cmd/expandybird/test/MissingResourceName.yaml @@ -18,4 +18,4 @@ resources: properties: service_port: 8080 target_port: 8080 - image: gcr.io/dm-k8s-prod/expandybird + image: gcr.io/dm-k8s-testing/expandybird diff --git a/expandybird/test/MissingTypeName.yaml b/cmd/expandybird/test/MissingTypeName.yaml similarity index 95% rename from expandybird/test/MissingTypeName.yaml rename to cmd/expandybird/test/MissingTypeName.yaml index f246d99f8..65bd433a4 100644 --- a/expandybird/test/MissingTypeName.yaml +++ b/cmd/expandybird/test/MissingTypeName.yaml @@ -18,4 +18,4 @@ resources: properties: service_port: 8080 target_port: 8080 - image: gcr.io/dm-k8s-prod/expandybird + image: gcr.io/dm-k8s-testing/expandybird diff --git a/expandybird/test/TestArchive.tar b/cmd/expandybird/test/TestArchive.tar similarity index 93% rename from expandybird/test/TestArchive.tar rename to cmd/expandybird/test/TestArchive.tar index 3b4e30e84..2c364b000 100644 Binary files a/expandybird/test/TestArchive.tar and b/cmd/expandybird/test/TestArchive.tar differ diff --git a/expandybird/test/ValidContent.yaml b/cmd/expandybird/test/ValidContent.yaml similarity index 93% rename from expandybird/test/ValidContent.yaml rename to cmd/expandybird/test/ValidContent.yaml index 0c342201e..37a32e153 100644 --- a/expandybird/test/ValidContent.yaml +++ b/cmd/expandybird/test/ValidContent.yaml @@ -22,6 +22,6 @@ resources: container_port: 8080 external_service: true replicas: 3 - image: gcr.io/dm-k8s-prod/expandybird + image: gcr.io/dm-k8s-testing/expandybird labels: app: expandybird \ No newline at end of file diff --git a/expandybird/test/replicatedservice.py b/cmd/expandybird/test/replicatedservice.py similarity index 100% rename from expandybird/test/replicatedservice.py rename to cmd/expandybird/test/replicatedservice.py diff --git a/expandybird/test/schemas/bad.jinja.schema b/cmd/expandybird/test/schemas/bad.jinja.schema similarity index 100% rename from expandybird/test/schemas/bad.jinja.schema rename to cmd/expandybird/test/schemas/bad.jinja.schema diff --git a/expandybird/test/schemas/default_ref.jinja.schema b/cmd/expandybird/test/schemas/default_ref.jinja.schema similarity index 100% rename from expandybird/test/schemas/default_ref.jinja.schema rename to cmd/expandybird/test/schemas/default_ref.jinja.schema diff --git a/expandybird/test/schemas/defaults.jinja.schema b/cmd/expandybird/test/schemas/defaults.jinja.schema similarity index 100% rename from expandybird/test/schemas/defaults.jinja.schema rename to cmd/expandybird/test/schemas/defaults.jinja.schema diff --git a/expandybird/test/schemas/defaults.py.schema b/cmd/expandybird/test/schemas/defaults.py.schema similarity index 100% rename from expandybird/test/schemas/defaults.py.schema rename to cmd/expandybird/test/schemas/defaults.py.schema diff --git a/expandybird/test/schemas/invalid_default.jinja.schema b/cmd/expandybird/test/schemas/invalid_default.jinja.schema similarity index 100% rename from expandybird/test/schemas/invalid_default.jinja.schema rename to cmd/expandybird/test/schemas/invalid_default.jinja.schema diff --git a/expandybird/test/schemas/invalid_reference.py.schema b/cmd/expandybird/test/schemas/invalid_reference.py.schema similarity index 100% rename from expandybird/test/schemas/invalid_reference.py.schema rename to cmd/expandybird/test/schemas/invalid_reference.py.schema diff --git a/expandybird/test/schemas/invalid_reference_schema.py.schema b/cmd/expandybird/test/schemas/invalid_reference_schema.py.schema similarity index 100% rename from expandybird/test/schemas/invalid_reference_schema.py.schema rename to cmd/expandybird/test/schemas/invalid_reference_schema.py.schema diff --git a/expandybird/test/schemas/metadata.py.schema b/cmd/expandybird/test/schemas/metadata.py.schema similarity index 100% rename from expandybird/test/schemas/metadata.py.schema rename to cmd/expandybird/test/schemas/metadata.py.schema diff --git a/expandybird/test/schemas/missing_quote.py.schema b/cmd/expandybird/test/schemas/missing_quote.py.schema similarity index 100% rename from expandybird/test/schemas/missing_quote.py.schema rename to cmd/expandybird/test/schemas/missing_quote.py.schema diff --git a/expandybird/test/schemas/nested_defaults.py.schema b/cmd/expandybird/test/schemas/nested_defaults.py.schema similarity index 100% rename from expandybird/test/schemas/nested_defaults.py.schema rename to cmd/expandybird/test/schemas/nested_defaults.py.schema diff --git a/expandybird/test/schemas/numbers.py.schema b/cmd/expandybird/test/schemas/numbers.py.schema similarity index 100% rename from expandybird/test/schemas/numbers.py.schema rename to cmd/expandybird/test/schemas/numbers.py.schema diff --git a/expandybird/test/schemas/ref_nested_defaults.py.schema b/cmd/expandybird/test/schemas/ref_nested_defaults.py.schema similarity index 100% rename from expandybird/test/schemas/ref_nested_defaults.py.schema rename to cmd/expandybird/test/schemas/ref_nested_defaults.py.schema diff --git a/expandybird/test/schemas/reference.jinja.schema b/cmd/expandybird/test/schemas/reference.jinja.schema similarity index 100% rename from expandybird/test/schemas/reference.jinja.schema rename to cmd/expandybird/test/schemas/reference.jinja.schema diff --git a/expandybird/test/schemas/req_default_ref.py.schema b/cmd/expandybird/test/schemas/req_default_ref.py.schema similarity index 100% rename from expandybird/test/schemas/req_default_ref.py.schema rename to cmd/expandybird/test/schemas/req_default_ref.py.schema diff --git a/expandybird/test/schemas/required.jinja.schema b/cmd/expandybird/test/schemas/required.jinja.schema similarity index 100% rename from expandybird/test/schemas/required.jinja.schema rename to cmd/expandybird/test/schemas/required.jinja.schema diff --git a/expandybird/test/schemas/required_default.jinja.schema b/cmd/expandybird/test/schemas/required_default.jinja.schema similarity index 100% rename from expandybird/test/schemas/required_default.jinja.schema rename to cmd/expandybird/test/schemas/required_default.jinja.schema diff --git a/expandybird/test/templates/description_text.txt b/cmd/expandybird/test/templates/description_text.txt similarity index 100% rename from expandybird/test/templates/description_text.txt rename to cmd/expandybird/test/templates/description_text.txt diff --git a/expandybird/test/templates/duplicate_names.yaml b/cmd/expandybird/test/templates/duplicate_names.yaml similarity index 100% rename from expandybird/test/templates/duplicate_names.yaml rename to cmd/expandybird/test/templates/duplicate_names.yaml diff --git a/expandybird/test/templates/duplicate_names_B.jinja b/cmd/expandybird/test/templates/duplicate_names_B.jinja similarity index 100% rename from expandybird/test/templates/duplicate_names_B.jinja rename to cmd/expandybird/test/templates/duplicate_names_B.jinja diff --git a/expandybird/test/templates/duplicate_names_C.jinja b/cmd/expandybird/test/templates/duplicate_names_C.jinja similarity index 100% rename from expandybird/test/templates/duplicate_names_C.jinja rename to cmd/expandybird/test/templates/duplicate_names_C.jinja diff --git a/expandybird/test/templates/duplicate_names_in_subtemplates.jinja b/cmd/expandybird/test/templates/duplicate_names_in_subtemplates.jinja similarity index 100% rename from expandybird/test/templates/duplicate_names_in_subtemplates.jinja rename to cmd/expandybird/test/templates/duplicate_names_in_subtemplates.jinja diff --git a/expandybird/test/templates/duplicate_names_in_subtemplates.yaml b/cmd/expandybird/test/templates/duplicate_names_in_subtemplates.yaml similarity index 100% rename from expandybird/test/templates/duplicate_names_in_subtemplates.yaml rename to cmd/expandybird/test/templates/duplicate_names_in_subtemplates.yaml diff --git a/expandybird/test/templates/duplicate_names_mixed_level.yaml b/cmd/expandybird/test/templates/duplicate_names_mixed_level.yaml similarity index 100% rename from expandybird/test/templates/duplicate_names_mixed_level.yaml rename to cmd/expandybird/test/templates/duplicate_names_mixed_level.yaml diff --git a/expandybird/test/templates/duplicate_names_mixed_level_result.yaml b/cmd/expandybird/test/templates/duplicate_names_mixed_level_result.yaml similarity index 100% rename from expandybird/test/templates/duplicate_names_mixed_level_result.yaml rename to cmd/expandybird/test/templates/duplicate_names_mixed_level_result.yaml diff --git a/expandybird/test/templates/duplicate_names_parent_child.yaml b/cmd/expandybird/test/templates/duplicate_names_parent_child.yaml similarity index 100% rename from expandybird/test/templates/duplicate_names_parent_child.yaml rename to cmd/expandybird/test/templates/duplicate_names_parent_child.yaml diff --git a/expandybird/test/templates/duplicate_names_parent_child_result.yaml b/cmd/expandybird/test/templates/duplicate_names_parent_child_result.yaml similarity index 100% rename from expandybird/test/templates/duplicate_names_parent_child_result.yaml rename to cmd/expandybird/test/templates/duplicate_names_parent_child_result.yaml diff --git a/expandybird/test/templates/helper.jinja b/cmd/expandybird/test/templates/helper.jinja similarity index 100% rename from expandybird/test/templates/helper.jinja rename to cmd/expandybird/test/templates/helper.jinja diff --git a/expandybird/test/templates/helper.jinja.schema b/cmd/expandybird/test/templates/helper.jinja.schema similarity index 100% rename from expandybird/test/templates/helper.jinja.schema rename to cmd/expandybird/test/templates/helper.jinja.schema diff --git a/expandybird/test/templates/helpers/common.jinja b/cmd/expandybird/test/templates/helpers/common.jinja similarity index 100% rename from expandybird/test/templates/helpers/common.jinja rename to cmd/expandybird/test/templates/helpers/common.jinja diff --git a/expandybird/test/templates/helpers/common.py b/cmd/expandybird/test/templates/helpers/common.py similarity index 100% rename from expandybird/test/templates/helpers/common.py rename to cmd/expandybird/test/templates/helpers/common.py diff --git a/expandybird/test/templates/helpers/extra/__init__.py b/cmd/expandybird/test/templates/helpers/extra/__init__.py similarity index 100% rename from expandybird/test/templates/helpers/extra/__init__.py rename to cmd/expandybird/test/templates/helpers/extra/__init__.py diff --git a/expandybird/test/templates/helpers/extra/common2.py b/cmd/expandybird/test/templates/helpers/extra/common2.py similarity index 100% rename from expandybird/test/templates/helpers/extra/common2.py rename to cmd/expandybird/test/templates/helpers/extra/common2.py diff --git a/expandybird/test/templates/invalid_config.yaml b/cmd/expandybird/test/templates/invalid_config.yaml similarity index 100% rename from expandybird/test/templates/invalid_config.yaml rename to cmd/expandybird/test/templates/invalid_config.yaml diff --git a/expandybird/test/templates/jinja_defaults.jinja b/cmd/expandybird/test/templates/jinja_defaults.jinja similarity index 100% rename from expandybird/test/templates/jinja_defaults.jinja rename to cmd/expandybird/test/templates/jinja_defaults.jinja diff --git a/expandybird/test/templates/jinja_defaults.jinja.schema b/cmd/expandybird/test/templates/jinja_defaults.jinja.schema similarity index 100% rename from expandybird/test/templates/jinja_defaults.jinja.schema rename to cmd/expandybird/test/templates/jinja_defaults.jinja.schema diff --git a/expandybird/test/templates/jinja_defaults.yaml b/cmd/expandybird/test/templates/jinja_defaults.yaml similarity index 100% rename from expandybird/test/templates/jinja_defaults.yaml rename to cmd/expandybird/test/templates/jinja_defaults.yaml diff --git a/expandybird/test/templates/jinja_defaults_result.yaml b/cmd/expandybird/test/templates/jinja_defaults_result.yaml similarity index 100% rename from expandybird/test/templates/jinja_defaults_result.yaml rename to cmd/expandybird/test/templates/jinja_defaults_result.yaml diff --git a/expandybird/test/templates/jinja_missing_required.jinja b/cmd/expandybird/test/templates/jinja_missing_required.jinja similarity index 100% rename from expandybird/test/templates/jinja_missing_required.jinja rename to cmd/expandybird/test/templates/jinja_missing_required.jinja diff --git a/expandybird/test/templates/jinja_missing_required.jinja.schema b/cmd/expandybird/test/templates/jinja_missing_required.jinja.schema similarity index 100% rename from expandybird/test/templates/jinja_missing_required.jinja.schema rename to cmd/expandybird/test/templates/jinja_missing_required.jinja.schema diff --git a/expandybird/test/templates/jinja_missing_required.yaml b/cmd/expandybird/test/templates/jinja_missing_required.yaml similarity index 100% rename from expandybird/test/templates/jinja_missing_required.yaml rename to cmd/expandybird/test/templates/jinja_missing_required.yaml diff --git a/expandybird/test/templates/jinja_multiple_errors.jinja b/cmd/expandybird/test/templates/jinja_multiple_errors.jinja similarity index 100% rename from expandybird/test/templates/jinja_multiple_errors.jinja rename to cmd/expandybird/test/templates/jinja_multiple_errors.jinja diff --git a/expandybird/test/templates/jinja_multiple_errors.jinja.schema b/cmd/expandybird/test/templates/jinja_multiple_errors.jinja.schema similarity index 100% rename from expandybird/test/templates/jinja_multiple_errors.jinja.schema rename to cmd/expandybird/test/templates/jinja_multiple_errors.jinja.schema diff --git a/expandybird/test/templates/jinja_multiple_errors.yaml b/cmd/expandybird/test/templates/jinja_multiple_errors.yaml similarity index 100% rename from expandybird/test/templates/jinja_multiple_errors.yaml rename to cmd/expandybird/test/templates/jinja_multiple_errors.yaml diff --git a/expandybird/test/templates/jinja_noparams.jinja b/cmd/expandybird/test/templates/jinja_noparams.jinja similarity index 100% rename from expandybird/test/templates/jinja_noparams.jinja rename to cmd/expandybird/test/templates/jinja_noparams.jinja diff --git a/expandybird/test/templates/jinja_noparams.yaml b/cmd/expandybird/test/templates/jinja_noparams.yaml similarity index 100% rename from expandybird/test/templates/jinja_noparams.yaml rename to cmd/expandybird/test/templates/jinja_noparams.yaml diff --git a/expandybird/test/templates/jinja_noparams_result.yaml b/cmd/expandybird/test/templates/jinja_noparams_result.yaml similarity index 100% rename from expandybird/test/templates/jinja_noparams_result.yaml rename to cmd/expandybird/test/templates/jinja_noparams_result.yaml diff --git a/expandybird/test/templates/jinja_template.jinja b/cmd/expandybird/test/templates/jinja_template.jinja similarity index 100% rename from expandybird/test/templates/jinja_template.jinja rename to cmd/expandybird/test/templates/jinja_template.jinja diff --git a/expandybird/test/templates/jinja_template.yaml b/cmd/expandybird/test/templates/jinja_template.yaml similarity index 100% rename from expandybird/test/templates/jinja_template.yaml rename to cmd/expandybird/test/templates/jinja_template.yaml diff --git a/expandybird/test/templates/jinja_template_result.yaml b/cmd/expandybird/test/templates/jinja_template_result.yaml similarity index 100% rename from expandybird/test/templates/jinja_template_result.yaml rename to cmd/expandybird/test/templates/jinja_template_result.yaml diff --git a/expandybird/test/templates/jinja_template_with_env.jinja b/cmd/expandybird/test/templates/jinja_template_with_env.jinja similarity index 100% rename from expandybird/test/templates/jinja_template_with_env.jinja rename to cmd/expandybird/test/templates/jinja_template_with_env.jinja diff --git a/expandybird/test/templates/jinja_template_with_env.yaml b/cmd/expandybird/test/templates/jinja_template_with_env.yaml similarity index 100% rename from expandybird/test/templates/jinja_template_with_env.yaml rename to cmd/expandybird/test/templates/jinja_template_with_env.yaml diff --git a/expandybird/test/templates/jinja_template_with_env_result.yaml b/cmd/expandybird/test/templates/jinja_template_with_env_result.yaml similarity index 100% rename from expandybird/test/templates/jinja_template_with_env_result.yaml rename to cmd/expandybird/test/templates/jinja_template_with_env_result.yaml diff --git a/expandybird/test/templates/jinja_template_with_import.jinja b/cmd/expandybird/test/templates/jinja_template_with_import.jinja similarity index 100% rename from expandybird/test/templates/jinja_template_with_import.jinja rename to cmd/expandybird/test/templates/jinja_template_with_import.jinja diff --git a/expandybird/test/templates/jinja_template_with_import.yaml b/cmd/expandybird/test/templates/jinja_template_with_import.yaml similarity index 100% rename from expandybird/test/templates/jinja_template_with_import.yaml rename to cmd/expandybird/test/templates/jinja_template_with_import.yaml diff --git a/expandybird/test/templates/jinja_template_with_import_result.yaml b/cmd/expandybird/test/templates/jinja_template_with_import_result.yaml similarity index 100% rename from expandybird/test/templates/jinja_template_with_import_result.yaml rename to cmd/expandybird/test/templates/jinja_template_with_import_result.yaml diff --git a/expandybird/test/templates/jinja_template_with_inlinedfile.jinja b/cmd/expandybird/test/templates/jinja_template_with_inlinedfile.jinja similarity index 100% rename from expandybird/test/templates/jinja_template_with_inlinedfile.jinja rename to cmd/expandybird/test/templates/jinja_template_with_inlinedfile.jinja diff --git a/expandybird/test/templates/jinja_template_with_inlinedfile.yaml b/cmd/expandybird/test/templates/jinja_template_with_inlinedfile.yaml similarity index 100% rename from expandybird/test/templates/jinja_template_with_inlinedfile.yaml rename to cmd/expandybird/test/templates/jinja_template_with_inlinedfile.yaml diff --git a/expandybird/test/templates/jinja_template_with_inlinedfile_result.yaml b/cmd/expandybird/test/templates/jinja_template_with_inlinedfile_result.yaml similarity index 100% rename from expandybird/test/templates/jinja_template_with_inlinedfile_result.yaml rename to cmd/expandybird/test/templates/jinja_template_with_inlinedfile_result.yaml diff --git a/expandybird/test/templates/jinja_unresolved.jinja b/cmd/expandybird/test/templates/jinja_unresolved.jinja similarity index 100% rename from expandybird/test/templates/jinja_unresolved.jinja rename to cmd/expandybird/test/templates/jinja_unresolved.jinja diff --git a/expandybird/test/templates/jinja_unresolved.yaml b/cmd/expandybird/test/templates/jinja_unresolved.yaml similarity index 100% rename from expandybird/test/templates/jinja_unresolved.yaml rename to cmd/expandybird/test/templates/jinja_unresolved.yaml diff --git a/expandybird/test/templates/no_properties.py b/cmd/expandybird/test/templates/no_properties.py similarity index 100% rename from expandybird/test/templates/no_properties.py rename to cmd/expandybird/test/templates/no_properties.py diff --git a/expandybird/test/templates/no_properties.yaml b/cmd/expandybird/test/templates/no_properties.yaml similarity index 100% rename from expandybird/test/templates/no_properties.yaml rename to cmd/expandybird/test/templates/no_properties.yaml diff --git a/expandybird/test/templates/no_properties_result.yaml b/cmd/expandybird/test/templates/no_properties_result.yaml similarity index 100% rename from expandybird/test/templates/no_properties_result.yaml rename to cmd/expandybird/test/templates/no_properties_result.yaml diff --git a/expandybird/test/templates/no_resources.py b/cmd/expandybird/test/templates/no_resources.py similarity index 100% rename from expandybird/test/templates/no_resources.py rename to cmd/expandybird/test/templates/no_resources.py diff --git a/expandybird/test/templates/no_resources.yaml b/cmd/expandybird/test/templates/no_resources.yaml similarity index 100% rename from expandybird/test/templates/no_resources.yaml rename to cmd/expandybird/test/templates/no_resources.yaml diff --git a/expandybird/test/templates/python_and_jinja_template.jinja b/cmd/expandybird/test/templates/python_and_jinja_template.jinja similarity index 100% rename from expandybird/test/templates/python_and_jinja_template.jinja rename to cmd/expandybird/test/templates/python_and_jinja_template.jinja diff --git a/expandybird/test/templates/python_and_jinja_template.py b/cmd/expandybird/test/templates/python_and_jinja_template.py similarity index 100% rename from expandybird/test/templates/python_and_jinja_template.py rename to cmd/expandybird/test/templates/python_and_jinja_template.py diff --git a/expandybird/test/templates/python_and_jinja_template.yaml b/cmd/expandybird/test/templates/python_and_jinja_template.yaml similarity index 100% rename from expandybird/test/templates/python_and_jinja_template.yaml rename to cmd/expandybird/test/templates/python_and_jinja_template.yaml diff --git a/expandybird/test/templates/python_and_jinja_template_result.yaml b/cmd/expandybird/test/templates/python_and_jinja_template_result.yaml similarity index 100% rename from expandybird/test/templates/python_and_jinja_template_result.yaml rename to cmd/expandybird/test/templates/python_and_jinja_template_result.yaml diff --git a/expandybird/test/templates/python_bad_schema.py b/cmd/expandybird/test/templates/python_bad_schema.py similarity index 100% rename from expandybird/test/templates/python_bad_schema.py rename to cmd/expandybird/test/templates/python_bad_schema.py diff --git a/expandybird/test/templates/python_bad_schema.py.schema b/cmd/expandybird/test/templates/python_bad_schema.py.schema similarity index 100% rename from expandybird/test/templates/python_bad_schema.py.schema rename to cmd/expandybird/test/templates/python_bad_schema.py.schema diff --git a/expandybird/test/templates/python_bad_schema.yaml b/cmd/expandybird/test/templates/python_bad_schema.yaml similarity index 100% rename from expandybird/test/templates/python_bad_schema.yaml rename to cmd/expandybird/test/templates/python_bad_schema.yaml diff --git a/expandybird/test/templates/python_noparams.py b/cmd/expandybird/test/templates/python_noparams.py similarity index 100% rename from expandybird/test/templates/python_noparams.py rename to cmd/expandybird/test/templates/python_noparams.py diff --git a/expandybird/test/templates/python_noparams.yaml b/cmd/expandybird/test/templates/python_noparams.yaml similarity index 100% rename from expandybird/test/templates/python_noparams.yaml rename to cmd/expandybird/test/templates/python_noparams.yaml diff --git a/expandybird/test/templates/python_noparams_result.yaml b/cmd/expandybird/test/templates/python_noparams_result.yaml similarity index 100% rename from expandybird/test/templates/python_noparams_result.yaml rename to cmd/expandybird/test/templates/python_noparams_result.yaml diff --git a/expandybird/test/templates/python_schema.py b/cmd/expandybird/test/templates/python_schema.py similarity index 100% rename from expandybird/test/templates/python_schema.py rename to cmd/expandybird/test/templates/python_schema.py diff --git a/expandybird/test/templates/python_schema.py.schema b/cmd/expandybird/test/templates/python_schema.py.schema similarity index 100% rename from expandybird/test/templates/python_schema.py.schema rename to cmd/expandybird/test/templates/python_schema.py.schema diff --git a/expandybird/test/templates/python_schema.yaml b/cmd/expandybird/test/templates/python_schema.yaml similarity index 100% rename from expandybird/test/templates/python_schema.yaml rename to cmd/expandybird/test/templates/python_schema.yaml diff --git a/expandybird/test/templates/python_schema_result.yaml b/cmd/expandybird/test/templates/python_schema_result.yaml similarity index 100% rename from expandybird/test/templates/python_schema_result.yaml rename to cmd/expandybird/test/templates/python_schema_result.yaml diff --git a/expandybird/test/templates/python_template.py b/cmd/expandybird/test/templates/python_template.py similarity index 100% rename from expandybird/test/templates/python_template.py rename to cmd/expandybird/test/templates/python_template.py diff --git a/expandybird/test/templates/python_template.yaml b/cmd/expandybird/test/templates/python_template.yaml similarity index 100% rename from expandybird/test/templates/python_template.yaml rename to cmd/expandybird/test/templates/python_template.yaml diff --git a/expandybird/test/templates/python_template_result.yaml b/cmd/expandybird/test/templates/python_template_result.yaml similarity index 100% rename from expandybird/test/templates/python_template_result.yaml rename to cmd/expandybird/test/templates/python_template_result.yaml diff --git a/expandybird/test/templates/python_template_with_env.py b/cmd/expandybird/test/templates/python_template_with_env.py similarity index 100% rename from expandybird/test/templates/python_template_with_env.py rename to cmd/expandybird/test/templates/python_template_with_env.py diff --git a/expandybird/test/templates/python_template_with_env.yaml b/cmd/expandybird/test/templates/python_template_with_env.yaml similarity index 100% rename from expandybird/test/templates/python_template_with_env.yaml rename to cmd/expandybird/test/templates/python_template_with_env.yaml diff --git a/expandybird/test/templates/python_template_with_env_result.yaml b/cmd/expandybird/test/templates/python_template_with_env_result.yaml similarity index 100% rename from expandybird/test/templates/python_template_with_env_result.yaml rename to cmd/expandybird/test/templates/python_template_with_env_result.yaml diff --git a/expandybird/test/templates/python_template_with_import.py b/cmd/expandybird/test/templates/python_template_with_import.py similarity index 100% rename from expandybird/test/templates/python_template_with_import.py rename to cmd/expandybird/test/templates/python_template_with_import.py diff --git a/expandybird/test/templates/python_template_with_import.yaml b/cmd/expandybird/test/templates/python_template_with_import.yaml similarity index 100% rename from expandybird/test/templates/python_template_with_import.yaml rename to cmd/expandybird/test/templates/python_template_with_import.yaml diff --git a/expandybird/test/templates/python_template_with_import_result.yaml b/cmd/expandybird/test/templates/python_template_with_import_result.yaml similarity index 100% rename from expandybird/test/templates/python_template_with_import_result.yaml rename to cmd/expandybird/test/templates/python_template_with_import_result.yaml diff --git a/expandybird/test/templates/python_template_with_inlinedfile.py b/cmd/expandybird/test/templates/python_template_with_inlinedfile.py similarity index 100% rename from expandybird/test/templates/python_template_with_inlinedfile.py rename to cmd/expandybird/test/templates/python_template_with_inlinedfile.py diff --git a/expandybird/test/templates/python_template_with_inlinedfile.yaml b/cmd/expandybird/test/templates/python_template_with_inlinedfile.yaml similarity index 100% rename from expandybird/test/templates/python_template_with_inlinedfile.yaml rename to cmd/expandybird/test/templates/python_template_with_inlinedfile.yaml diff --git a/expandybird/test/templates/python_template_with_inlinedfile_result.yaml b/cmd/expandybird/test/templates/python_template_with_inlinedfile_result.yaml similarity index 100% rename from expandybird/test/templates/python_template_with_inlinedfile_result.yaml rename to cmd/expandybird/test/templates/python_template_with_inlinedfile_result.yaml diff --git a/expandybird/test/templates/python_with_exception.py b/cmd/expandybird/test/templates/python_with_exception.py similarity index 100% rename from expandybird/test/templates/python_with_exception.py rename to cmd/expandybird/test/templates/python_with_exception.py diff --git a/expandybird/test/templates/python_with_exception.yaml b/cmd/expandybird/test/templates/python_with_exception.yaml similarity index 100% rename from expandybird/test/templates/python_with_exception.yaml rename to cmd/expandybird/test/templates/python_with_exception.yaml diff --git a/expandybird/test/templates/simple.yaml b/cmd/expandybird/test/templates/simple.yaml similarity index 100% rename from expandybird/test/templates/simple.yaml rename to cmd/expandybird/test/templates/simple.yaml diff --git a/expandybird/test/templates/simple_result.yaml b/cmd/expandybird/test/templates/simple_result.yaml similarity index 100% rename from expandybird/test/templates/simple_result.yaml rename to cmd/expandybird/test/templates/simple_result.yaml diff --git a/expandybird/test/templates/use_helper.jinja b/cmd/expandybird/test/templates/use_helper.jinja similarity index 100% rename from expandybird/test/templates/use_helper.jinja rename to cmd/expandybird/test/templates/use_helper.jinja diff --git a/expandybird/test/templates/use_helper.jinja.schema b/cmd/expandybird/test/templates/use_helper.jinja.schema similarity index 100% rename from expandybird/test/templates/use_helper.jinja.schema rename to cmd/expandybird/test/templates/use_helper.jinja.schema diff --git a/expandybird/test/templates/use_helper.yaml b/cmd/expandybird/test/templates/use_helper.yaml similarity index 100% rename from expandybird/test/templates/use_helper.yaml rename to cmd/expandybird/test/templates/use_helper.yaml diff --git a/expandybird/test/templates/use_helper_result.yaml b/cmd/expandybird/test/templates/use_helper_result.yaml similarity index 100% rename from expandybird/test/templates/use_helper_result.yaml rename to cmd/expandybird/test/templates/use_helper_result.yaml diff --git a/cmd/helm/chart.go b/cmd/helm/chart.go new file mode 100644 index 000000000..7d4a67dfa --- /dev/null +++ b/cmd/helm/chart.go @@ -0,0 +1,43 @@ +package main + +import ( + "github.com/codegangsta/cli" +) + +func init() { + addCommands(chartCommands()) +} + +func chartCommands() cli.Command { + return cli.Command{ + // Names following form prescribed here: http://is.gd/QUSEOF + Name: "chart", + Usage: "Perform chart-centered operations.", + Subcommands: []cli.Command{ + { + Name: "config", + Usage: "Create a configuration parameters file for this chart.", + ArgsUsage: "CHART", + }, + { + Name: "show", + Aliases: []string{"info"}, + Usage: "Provide details about this package.", + ArgsUsage: "CHART", + }, + { + Name: "scaffold", + }, + { + Name: "list", + Usage: "list all deployed charts, optionally constraining by pattern.", + ArgsUsage: "[PATTERN]", + }, + { + Name: "deployments", + Usage: "given a chart, show all the deployments that reference it.", + ArgsUsage: "CHART", + }, + }, + } +} diff --git a/cmd/helm/chart_upload.go b/cmd/helm/chart_upload.go new file mode 100644 index 000000000..182df9fb1 --- /dev/null +++ b/cmd/helm/chart_upload.go @@ -0,0 +1,99 @@ +package main + +import ( + "errors" + "fmt" + "os" + "regexp" + "strings" + + "github.com/aokoli/goutils" + "github.com/codegangsta/cli" + "github.com/kubernetes/deployment-manager/pkg/chart" + "github.com/kubernetes/deployment-manager/pkg/format" +) + +func uploadChart(c *cli.Context) error { + args := c.Args() + if len(args) < 1 { + format.Err("First argument, filename, is required. Try 'helm deploy --help'") + os.Exit(1) + } + + cname := c.String("name") + fname := args[0] + + if fname == "" { + return errors.New("A filename must be specified. For a tar archive, this is the name of the root template in the archive.") + } + + _, err := doUpload(fname, cname, c) + return err +} +func doUpload(filename, cname string, cxt *cli.Context) (string, error) { + + fi, err := os.Stat(filename) + if err != nil { + return "", err + } + + if fi.IsDir() { + format.Info("Chart is directory") + c, err := chart.LoadDir(filename) + if err != nil { + return "", err + } + if cname == "" { + cname = genName(c.Chartfile().Name) + } + + // TODO: Is it better to generate the file in temp dir like this, or + // just put it in the CWD? + //tdir, err := ioutil.TempDir("", "helm-") + //if err != nil { + //format.Warn("Could not create temporary directory. Using .") + //tdir = "." + //} else { + //defer os.RemoveAll(tdir) + //} + tdir := "." + tfile, err := chart.Save(c, tdir) + if err != nil { + return "", err + } + filename = tfile + } else if cname == "" { + n, _, e := parseTarName(filename) + if e != nil { + return "", e + } + cname = n + } + + // TODO: Add a version build metadata on the chart. + + if cxt.Bool("dry-run") { + format.Info("Prepared deploy %q using file %q", cname, filename) + return "", nil + } + + c := client(cxt) + return c.PostChart(filename, cname) +} + +func genName(pname string) string { + s, _ := goutils.RandomAlphaNumeric(8) + return fmt.Sprintf("%s-%s", pname, s) +} + +func parseTarName(name string) (string, string, error) { + tnregexp := regexp.MustCompile(chart.TarNameRegex) + if strings.HasSuffix(name, ".tgz") { + name = strings.TrimSuffix(name, ".tgz") + } + v := tnregexp.FindStringSubmatch(name) + if v == nil { + return name, "", fmt.Errorf("invalid name %s", name) + } + return v[1], v[2], nil +} diff --git a/cmd/helm/create.go b/cmd/helm/create.go new file mode 100644 index 000000000..a8fab3c20 --- /dev/null +++ b/cmd/helm/create.go @@ -0,0 +1,40 @@ +package main + +import ( + "errors" + "path/filepath" + + "github.com/codegangsta/cli" + "github.com/kubernetes/deployment-manager/pkg/chart" +) + +func init() { + addCommands(createCmd()) +} + +func createCmd() cli.Command { + return cli.Command{ + Name: "create", + Usage: "Create a new local chart for editing.", + Action: func(c *cli.Context) { run(c, create) }, + ArgsUsage: "NAME", + } +} + +func create(c *cli.Context) error { + args := c.Args() + if len(args) < 1 { + return errors.New("'helm create' requires a chart name as an argument") + } + + dir, name := filepath.Split(args[0]) + + cf := &chart.Chartfile{ + Name: name, + Description: "Created by Helm", + Version: "0.1.0", + } + + _, err := chart.Create(cf, dir) + return err +} diff --git a/cmd/helm/credential.go b/cmd/helm/credential.go new file mode 100644 index 000000000..f2afa369b --- /dev/null +++ b/cmd/helm/credential.go @@ -0,0 +1,41 @@ +package main + +import ( + "github.com/codegangsta/cli" +) + +func init() { + addCommands(credCommands()) +} + +func credCommands() cli.Command { + return cli.Command{ + Name: "credential", + Aliases: []string{"cred"}, + Usage: "Perform repository credential operations.", + Subcommands: []cli.Command{ + { + Name: "add", + Usage: "Add a credential to the remote manager.", + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "file,f", + Usage: "A JSON file with credential information.", + }, + }, + ArgsUsage: "CREDENTIAL", + }, + { + Name: "list", + Usage: "List the credentials on the remote manager.", + ArgsUsage: "", + }, + { + Name: "remove", + Aliases: []string{"rm"}, + Usage: "Remove a credential from the remote manager.", + ArgsUsage: "CREDENTIAL", + }, + }, + } +} diff --git a/cmd/helm/delete.go b/cmd/helm/delete.go new file mode 100644 index 000000000..cc2388515 --- /dev/null +++ b/cmd/helm/delete.go @@ -0,0 +1,34 @@ +package main + +import ( + "errors" + + "github.com/codegangsta/cli" + "github.com/kubernetes/deployment-manager/pkg/format" +) + +func init() { + addCommands(deleteCmd()) +} + +func deleteCmd() cli.Command { + return cli.Command{ + Name: "delete", + Usage: "Deletes the supplied deployment", + ArgsUsage: "DEPLOYMENT", + Action: func(c *cli.Context) { run(c, deleteDeployment) }, + } +} + +func deleteDeployment(c *cli.Context) error { + args := c.Args() + if len(args) < 1 { + return errors.New("First argument, deployment name, is required. Try 'helm get --help'") + } + name := args[0] + deployment, err := client(c).DeleteDeployment(name) + if err != nil { + return err + } + return format.YAML(deployment) +} diff --git a/cmd/helm/deploy.go b/cmd/helm/deploy.go new file mode 100644 index 000000000..58afbebe7 --- /dev/null +++ b/cmd/helm/deploy.go @@ -0,0 +1,105 @@ +package main + +import ( + "io/ioutil" + "os" + + "github.com/codegangsta/cli" + "github.com/kubernetes/deployment-manager/pkg/common" + "gopkg.in/yaml.v2" +) + +func init() { + addCommands(deployCmd()) +} + +func deployCmd() cli.Command { + return cli.Command{ + Name: "deploy", + Usage: "Deploy a chart into the cluster.", + ArgsUsage: "[CHART]", + Action: func(c *cli.Context) { run(c, deploy) }, + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "config,c", + Usage: "The configuration YAML file for this deployment.", + }, + cli.StringFlag{ + Name: "name", + Usage: "Name of deployment, used for deploy and update commands (defaults to template name)", + }, + // TODO: I think there is a Generic flag type that we can implement parsing with. + cli.StringFlag{ + Name: "properties,p", + Usage: "A comma-separated list of key=value pairs: 'foo=bar,foo2=baz'.", + }, + }, + } +} + +func deploy(c *cli.Context) error { + + // If there is a configuration file, use it. + cfg := &common.Configuration{} + if c.String("config") != "" { + if err := loadConfig(cfg, c.String("config")); err != nil { + return err + } + } else { + cfg.Resources = []*common.Resource{ + { + Properties: map[string]interface{}{}, + }, + } + } + + // If there is a chart specified on the commandline, override the config + // file with it. + args := c.Args() + if len(args) > 0 { + cname := args[0] + if isLocalChart(cname) { + // If we get here, we need to first package then upload the chart. + loc, err := doUpload(cname, "", c) + if err != nil { + return err + } + cfg.Resources[0].Name = loc + } else { + cfg.Resources[0].Type = cname + } + } + + // Override the name if one is passed in. + if name := c.String("name"); len(name) > 0 { + cfg.Resources[0].Name = name + } + + if props, err := parseProperties(c.String("properties")); err != nil { + return err + } else if len(props) > 0 { + // Coalesce the properties into the first props. We have no way of + // knowing which resource the properties are supposed to be part + // of. + for n, v := range props { + cfg.Resources[0].Properties[n] = v + } + } + + return client(c).PostDeployment(cfg) +} + +// isLocalChart returns true if the given path can be statted. +func isLocalChart(path string) bool { + _, err := os.Stat(path) + return err == nil +} + +// loadConfig loads a file into a common.Configuration. +func loadConfig(c *common.Configuration, filename string) error { + data, err := ioutil.ReadFile(filename) + if err != nil { + return err + } + return yaml.Unmarshal(data, c) +} diff --git a/cmd/helm/deployment.go b/cmd/helm/deployment.go new file mode 100644 index 000000000..bf06d2d24 --- /dev/null +++ b/cmd/helm/deployment.go @@ -0,0 +1,40 @@ +package main + +import ( + "github.com/codegangsta/cli" +) + +func init() { + addCommands(deploymentCommands()) +} + +func deploymentCommands() cli.Command { + return cli.Command{ + // Names following form prescribed here: http://is.gd/QUSEOF + Name: "deployment", + Usage: "Perform deployment-centered operations.", + Subcommands: []cli.Command{ + { + Name: "config", + Usage: "Dump the configuration file for this deployment.", + ArgsUsage: "DEPLOYMENT", + }, + { + Name: "manifest", + Usage: "Dump the Kubernetes manifest file for this deployment.", + ArgsUsage: "DEPLOYMENT", + }, + { + Name: "show", + Aliases: []string{"info"}, + Usage: "Provide details about this deployment.", + ArgsUsage: "", + }, + { + Name: "list", + Usage: "list all deployments, or filter by an optional pattern", + ArgsUsage: "PATTERN", + }, + }, + } +} diff --git a/cmd/helm/dm.go b/cmd/helm/dm.go new file mode 100644 index 000000000..3d2c48c0a --- /dev/null +++ b/cmd/helm/dm.go @@ -0,0 +1,118 @@ +package main + +import ( + "errors" + "os" + + "github.com/codegangsta/cli" + "github.com/kubernetes/deployment-manager/pkg/dm" + "github.com/kubernetes/deployment-manager/pkg/format" + "github.com/kubernetes/deployment-manager/pkg/kubectl" +) + +// ErrAlreadyInstalled indicates that DM is already installed. +var ErrAlreadyInstalled = errors.New("Already Installed") + +func init() { + addCommands(dmCmd()) +} + +func dmCmd() cli.Command { + return cli.Command{ + Name: "dm", + Usage: "Manage DM on Kubernetes", + Subcommands: []cli.Command{ + { + Name: "install", + Usage: "Install DM on Kubernetes.", + ArgsUsage: "", + Description: ``, + Flags: []cli.Flag{ + cli.BoolFlag{ + Name: "dry-run", + Usage: "Show what would be installed, but don't install anything.", + }, + }, + Action: func(c *cli.Context) { + if err := install(c.Bool("dry-run")); err != nil { + format.Err("%s (Run 'helm doctor' for more information)", err) + os.Exit(1) + } + }, + }, + { + Name: "uninstall", + Usage: "Uninstall the DM from Kubernetes.", + ArgsUsage: "", + Description: ``, + Flags: []cli.Flag{ + cli.BoolFlag{ + Name: "dry-run", + Usage: "Show what would be installed, but don't install anything.", + }, + }, + Action: func(c *cli.Context) { + if err := uninstall(c.Bool("dry-run")); err != nil { + format.Err("%s (Run 'helm doctor' for more information)", err) + os.Exit(1) + } + }, + }, + { + Name: "status", + Usage: "Show status of DM.", + ArgsUsage: "", + Action: func(c *cli.Context) { + format.Err("Not yet implemented") + os.Exit(1) + }, + }, + { + Name: "target", + Usage: "Displays information about cluster.", + ArgsUsage: "", + Action: func(c *cli.Context) { + if err := target(c.Bool("dry-run")); err != nil { + format.Err("%s (Is the cluster running?)", err) + os.Exit(1) + } + }, + Flags: []cli.Flag{ + cli.BoolFlag{ + Name: "dry-run", + Usage: "Only display the underlying kubectl commands.", + }, + }, + }, + }, + } +} + +func install(dryRun bool) error { + runner := getKubectlRunner(dryRun) + + out, err := dm.Install(runner) + if err != nil { + format.Err("Error installing: %s %s", out, err) + } + format.Msg(out) + return nil +} + +func uninstall(dryRun bool) error { + runner := getKubectlRunner(dryRun) + + out, err := dm.Uninstall(runner) + if err != nil { + format.Err("Error uninstalling: %s %s", out, err) + } + format.Msg(out) + return nil +} + +func getKubectlRunner(dryRun bool) kubectl.Runner { + if dryRun { + return &kubectl.PrintRunner{} + } + return &kubectl.RealRunner{} +} diff --git a/cmd/helm/doctor.go b/cmd/helm/doctor.go new file mode 100644 index 000000000..af8270c25 --- /dev/null +++ b/cmd/helm/doctor.go @@ -0,0 +1,33 @@ +package main + +import ( + "github.com/codegangsta/cli" + "github.com/kubernetes/deployment-manager/pkg/dm" + "github.com/kubernetes/deployment-manager/pkg/format" + "github.com/kubernetes/deployment-manager/pkg/kubectl" +) + +func init() { + addCommands(doctorCmd()) +} + +func doctorCmd() cli.Command { + return cli.Command{ + Name: "doctor", + Usage: "Run a series of checks for necessary prerequisites.", + ArgsUsage: "", + Action: func(c *cli.Context) { run(c, doctor) }, + } +} + +func doctor(c *cli.Context) error { + var runner kubectl.Runner + runner = &kubectl.RealRunner{} + if dm.IsInstalled(runner) { + format.Success("You have everything you need. Go forth my friend!") + } else { + format.Warning("Looks like you don't have DM installed.\nRun: `helm install`") + } + + return nil +} diff --git a/cmd/helm/get.go b/cmd/helm/get.go new file mode 100644 index 000000000..accede093 --- /dev/null +++ b/cmd/helm/get.go @@ -0,0 +1,34 @@ +package main + +import ( + "errors" + + "github.com/codegangsta/cli" + "github.com/kubernetes/deployment-manager/pkg/format" +) + +func init() { + addCommands(getCmd()) +} + +func getCmd() cli.Command { + return cli.Command{ + Name: "get", + ArgsUsage: "DEPLOYMENT", + Usage: "Retrieves the supplied deployment", + Action: func(c *cli.Context) { run(c, get) }, + } +} + +func get(c *cli.Context) error { + args := c.Args() + if len(args) < 1 { + return errors.New("First argument, deployment name, is required. Try 'helm get --help'") + } + name := args[0] + deployment, err := client(c).GetDeployment(name) + if err != nil { + return err + } + return format.YAML(deployment) +} diff --git a/cmd/helm/helm.go b/cmd/helm/helm.go new file mode 100644 index 000000000..78055f752 --- /dev/null +++ b/cmd/helm/helm.go @@ -0,0 +1,88 @@ +package main + +import ( + "os" + + "github.com/codegangsta/cli" + "github.com/kubernetes/deployment-manager/pkg/dm" + "github.com/kubernetes/deployment-manager/pkg/format" +) + +var version = "0.0.1" + +var commands []cli.Command + +func init() { + addCommands(cmds()...) +} + +func main() { + app := cli.NewApp() + app.Name = "helm" + app.Version = version + app.Usage = `Deploy and manage packages.` + app.Commands = commands + + // TODO: make better + app.Flags = []cli.Flag{ + cli.StringFlag{ + Name: "host,u", + Usage: "The URL of the DM server.", + EnvVar: "HELM_HOST", + Value: "https://localhost:8000/", + }, + cli.IntFlag{ + Name: "timeout", + Usage: "Time in seconds to wait for response", + Value: 10, + }, + cli.BoolFlag{ + Name: "debug", + Usage: "Enable verbose debugging output", + }, + } + app.Run(os.Args) +} + +func cmds() []cli.Command { + return []cli.Command{ + { + Name: "init", + Usage: "Initialize the client and install DM on Kubernetes.", + Description: ``, + Flags: []cli.Flag{ + cli.BoolFlag{ + Name: "dry-run", + Usage: "Show what would be installed, but don't install anything.", + }, + }, + Action: func(c *cli.Context) { + if err := install(c.Bool("dry-run")); err != nil { + format.Err("%s (Run 'helm doctor' for more information)", err) + os.Exit(1) + } + }, + }, + { + Name: "search", + }, + } +} + +func addCommands(cmds ...cli.Command) { + commands = append(commands, cmds...) +} + +func run(c *cli.Context, f func(c *cli.Context) error) { + if err := f(c); err != nil { + os.Stderr.Write([]byte(err.Error())) + os.Exit(1) + } +} + +func client(c *cli.Context) *dm.Client { + host := c.GlobalString("host") + debug := c.GlobalBool("debug") + timeout := c.GlobalInt("timeout") + return dm.NewClient(host).SetDebug(debug).SetTimeout(timeout) +} diff --git a/cmd/helm/lint.go b/cmd/helm/lint.go new file mode 100644 index 000000000..54c899151 --- /dev/null +++ b/cmd/helm/lint.go @@ -0,0 +1,17 @@ +package main + +import ( + "github.com/codegangsta/cli" +) + +func init() { + addCommands(lintCmd()) +} + +func lintCmd() cli.Command { + return cli.Command{ + Name: "lint", + Usage: "Evaluate a chart's conformance to the specification.", + ArgsUsage: "PATH [PATH...]", + } +} diff --git a/cmd/helm/list.go b/cmd/helm/list.go new file mode 100644 index 000000000..a17ac569d --- /dev/null +++ b/cmd/helm/list.go @@ -0,0 +1,26 @@ +package main + +import ( + "github.com/codegangsta/cli" + "github.com/kubernetes/deployment-manager/pkg/format" +) + +func init() { + addCommands(listCmd()) +} + +func listCmd() cli.Command { + return cli.Command{ + Name: "list", + Usage: "Lists the deployments in the cluster", + Action: func(c *cli.Context) { run(c, list) }, + } +} + +func list(c *cli.Context) error { + list, err := client(c).ListDeployments() + if err != nil { + return err + } + return format.YAML(list) +} diff --git a/cmd/helm/pack.go b/cmd/helm/pack.go new file mode 100644 index 000000000..9b807a432 --- /dev/null +++ b/cmd/helm/pack.go @@ -0,0 +1,48 @@ +package main + +import ( + "errors" + "fmt" + "os" + + "github.com/codegangsta/cli" + "github.com/kubernetes/deployment-manager/pkg/chart" + "github.com/kubernetes/deployment-manager/pkg/format" +) + +func init() { + addCommands(packageCmd()) +} + +func packageCmd() cli.Command { + return cli.Command{ + Name: "package", + Aliases: []string{"pack"}, + Usage: "Given a chart directory, package it into a release.", + ArgsUsage: "PATH", + Action: func(c *cli.Context) { run(c, pack) }, + } +} + +func pack(cxt *cli.Context) error { + args := cxt.Args() + if len(args) < 1 { + return errors.New("'helm package' requires a path to a chart directory as an argument") + } + + dir := args[0] + if fi, err := os.Stat(dir); err != nil { + return fmt.Errorf("Could not find directory %s: %s", dir, err) + } else if !fi.IsDir() { + return fmt.Errorf("Not a directory: %s", dir) + } + + c, err := chart.LoadDir(dir) + if err != nil { + return fmt.Errorf("Failed to load %s: %s", dir, err) + } + + fname, err := chart.Save(c, ".") + format.Msg(fname) + return nil +} diff --git a/cmd/helm/properties.go b/cmd/helm/properties.go new file mode 100644 index 000000000..9632c95f6 --- /dev/null +++ b/cmd/helm/properties.go @@ -0,0 +1,40 @@ +package main + +import ( + "errors" + "strconv" + "strings" +) + +// TODO: The concept of property here is really simple. We could definitely get +// better about the values we allow. Also, we need some validation on the names. + +var errInvalidProperty = errors.New("property is not in name=value format") + +// parseProperties is a utility for parsing a comma-separated key=value string. +func parseProperties(kvstr string) (map[string]interface{}, error) { + properties := map[string]interface{}{} + + if len(kvstr) == 0 { + return properties, nil + } + + pairs := strings.Split(kvstr, ",") + for _, p := range pairs { + // Allow for "k=v, k=v" + p = strings.TrimSpace(p) + pair := strings.Split(p, "=") + if len(pair) == 1 { + return properties, errInvalidProperty + } + + // If the value looks int-like, convert it. + if i, err := strconv.Atoi(pair[1]); err == nil { + properties[pair[0]] = pair[1] + } else { + properties[pair[0]] = i + } + } + + return properties, nil +} diff --git a/cmd/helm/redeploy.go b/cmd/helm/redeploy.go new file mode 100644 index 000000000..18bbb5168 --- /dev/null +++ b/cmd/helm/redeploy.go @@ -0,0 +1,23 @@ +package main + +import ( + "github.com/codegangsta/cli" +) + +func init() { + addCommands(redeployCommand()) +} + +func redeployCommand() cli.Command { + return cli.Command{ + Name: "redeploy", + Usage: "update an existing deployment with a new configuration.", + ArgsUsage: "DEPLOYMENT", + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "config,f", + Usage: "Configuration values file.", + }, + }, + } +} diff --git a/cmd/helm/release.go b/cmd/helm/release.go new file mode 100644 index 000000000..a9e1a7c71 --- /dev/null +++ b/cmd/helm/release.go @@ -0,0 +1,23 @@ +package main + +import ( + "github.com/codegangsta/cli" +) + +func init() { + addCommands(releaseCmd()) +} + +func releaseCmd() cli.Command { + return cli.Command{ + Name: "release", + Usage: "Release a chart to a remote chart repository.", + ArgsUsage: "PATH", + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "destination,u", + Usage: "Destination URL to which this will be POSTed.", + }, + }, + } +} diff --git a/cmd/helm/repository.go b/cmd/helm/repository.go new file mode 100644 index 000000000..463035d31 --- /dev/null +++ b/cmd/helm/repository.go @@ -0,0 +1,46 @@ +package main + +import ( + "github.com/codegangsta/cli" +) + +func init() { + addCommands(repoCommands()) +} + +func repoCommands() cli.Command { + return cli.Command{ + Name: "repository", + Aliases: []string{"repo"}, + Usage: "Perform repository operations.", + Subcommands: []cli.Command{ + { + Name: "add", + Usage: "Add a repository to the remote manager.", + ArgsUsage: "REPOSITORY", + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "cred", + Usage: "The name of the credential.", + }, + }, + }, + { + Name: "show", + Usage: "Show the repository details for a given repository.", + ArgsUsage: "REPOSITORY", + }, + { + Name: "list", + Usage: "List the repositories on the remote manager.", + ArgsUsage: "", + }, + { + Name: "remove", + Aliases: []string{"rm"}, + Usage: "Remove a repository from the remote manager.", + ArgsUsage: "REPOSITORY", + }, + }, + } +} diff --git a/cmd/helm/status.go b/cmd/helm/status.go new file mode 100644 index 000000000..d43466ee2 --- /dev/null +++ b/cmd/helm/status.go @@ -0,0 +1,17 @@ +package main + +import ( + "github.com/codegangsta/cli" +) + +func init() { + addCommands(statusCommand()) +} + +func statusCommand() cli.Command { + return cli.Command{ + Name: "status", + Usage: "Provide status on a named deployment.", + ArgsUsage: "DEPLOYMENT", + } +} diff --git a/cmd/helm/target.go b/cmd/helm/target.go new file mode 100644 index 000000000..b6cc65b87 --- /dev/null +++ b/cmd/helm/target.go @@ -0,0 +1,21 @@ +package main + +import ( + "fmt" + + "github.com/kubernetes/deployment-manager/pkg/format" + "github.com/kubernetes/deployment-manager/pkg/kubectl" +) + +func target(dryRun bool) error { + client := kubectl.Client + if dryRun { + client = kubectl.PrintRunner{} + } + out, err := client.ClusterInfo() + if err != nil { + return fmt.Errorf("%s (%s)", out, err) + } + format.Msg(string(out)) + return nil +} diff --git a/manager/Dockerfile b/cmd/manager/Dockerfile similarity index 100% rename from manager/Dockerfile rename to cmd/manager/Dockerfile diff --git a/manager/Makefile b/cmd/manager/Makefile similarity index 98% rename from manager/Makefile rename to cmd/manager/Makefile index 209c874f2..2e3a2ad55 100644 --- a/manager/Makefile +++ b/cmd/manager/Makefile @@ -19,6 +19,7 @@ include ../include.mk DOCKER_REGISTRY := gcr.io PREFIX := $(DOCKER_REGISTRY)/$(PROJECT) IMAGE := manager +TAG := latest ROOT_DIR := $(abspath ./..) DIR = $(ROOT_DIR) diff --git a/manager/deployments.go b/cmd/manager/deployments.go similarity index 97% rename from manager/deployments.go rename to cmd/manager/deployments.go index 37de85909..993dc1678 100644 --- a/manager/deployments.go +++ b/cmd/manager/deployments.go @@ -33,13 +33,13 @@ import ( "github.com/ghodss/yaml" "github.com/gorilla/mux" - "github.com/kubernetes/deployment-manager/common" - "github.com/kubernetes/deployment-manager/manager/manager" - "github.com/kubernetes/deployment-manager/manager/repository" - "github.com/kubernetes/deployment-manager/manager/repository/persistent" - "github.com/kubernetes/deployment-manager/manager/repository/transient" - "github.com/kubernetes/deployment-manager/registry" - "github.com/kubernetes/deployment-manager/util" + "github.com/kubernetes/deployment-manager/cmd/manager/manager" + "github.com/kubernetes/deployment-manager/cmd/manager/repository" + "github.com/kubernetes/deployment-manager/cmd/manager/repository/persistent" + "github.com/kubernetes/deployment-manager/cmd/manager/repository/transient" + "github.com/kubernetes/deployment-manager/pkg/common" + "github.com/kubernetes/deployment-manager/pkg/registry" + "github.com/kubernetes/deployment-manager/pkg/util" ) var deployments = []Route{ diff --git a/manager/main.go b/cmd/manager/main.go similarity index 95% rename from manager/main.go rename to cmd/manager/main.go index 0009a41d4..a17369a7d 100644 --- a/manager/main.go +++ b/cmd/manager/main.go @@ -17,8 +17,8 @@ limitations under the License. package main import ( - "github.com/kubernetes/deployment-manager/util" - "github.com/kubernetes/deployment-manager/version" + "github.com/kubernetes/deployment-manager/pkg/util" + "github.com/kubernetes/deployment-manager/pkg/version" "flag" "fmt" diff --git a/manager/manager/deployer.go b/cmd/manager/manager/deployer.go similarity index 98% rename from manager/manager/deployer.go rename to cmd/manager/manager/deployer.go index 953f5a806..9c9c70190 100644 --- a/manager/manager/deployer.go +++ b/cmd/manager/manager/deployer.go @@ -6,7 +6,7 @@ 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. @@ -28,7 +28,7 @@ import ( "time" "github.com/ghodss/yaml" - "github.com/kubernetes/deployment-manager/common" + "github.com/kubernetes/deployment-manager/pkg/common" ) // Deployer abstracts interactions with the expander and deployer services. diff --git a/manager/manager/deployer_test.go b/cmd/manager/manager/deployer_test.go similarity index 98% rename from manager/manager/deployer_test.go rename to cmd/manager/manager/deployer_test.go index 535536364..6947119ae 100644 --- a/manager/manager/deployer_test.go +++ b/cmd/manager/manager/deployer_test.go @@ -6,7 +6,7 @@ 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. @@ -26,8 +26,8 @@ import ( "strings" "testing" - "github.com/kubernetes/deployment-manager/util" - "github.com/kubernetes/deployment-manager/common" + "github.com/kubernetes/deployment-manager/pkg/common" + "github.com/kubernetes/deployment-manager/pkg/util" "github.com/ghodss/yaml" ) diff --git a/manager/manager/expander.go b/cmd/manager/manager/expander.go similarity index 99% rename from manager/manager/expander.go rename to cmd/manager/manager/expander.go index f41406cfe..bc3fc2bb5 100644 --- a/manager/manager/expander.go +++ b/cmd/manager/manager/expander.go @@ -24,7 +24,7 @@ import ( "net/http" "github.com/ghodss/yaml" - "github.com/kubernetes/deployment-manager/common" + "github.com/kubernetes/deployment-manager/pkg/common" ) const ( diff --git a/manager/manager/expander_test.go b/cmd/manager/manager/expander_test.go similarity index 98% rename from manager/manager/expander_test.go rename to cmd/manager/manager/expander_test.go index 59d302cbf..6e803e6ea 100644 --- a/manager/manager/expander_test.go +++ b/cmd/manager/manager/expander_test.go @@ -6,7 +6,7 @@ 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. @@ -26,8 +26,8 @@ import ( "strings" "testing" - "github.com/kubernetes/deployment-manager/util" - "github.com/kubernetes/deployment-manager/common" + "github.com/kubernetes/deployment-manager/pkg/common" + "github.com/kubernetes/deployment-manager/pkg/util" "github.com/ghodss/yaml" ) @@ -64,15 +64,15 @@ resources: `) var validImportFilesTestCaseData = []*common.ImportFile{ - &common.ImportFile{ + { Name: "test-type.py", Content: "test-type.py validTemplateTestCaseData content", }, - &common.ImportFile{ + { Name: "test.py", Content: "test.py validTemplateTestCaseData content", }, - &common.ImportFile{ + { Name: "test2.py", Content: "test2.py validTemplateTestCaseData content", }, diff --git a/manager/manager/manager.go b/cmd/manager/manager/manager.go similarity index 98% rename from manager/manager/manager.go rename to cmd/manager/manager/manager.go index 801b09fab..e62488256 100644 --- a/manager/manager/manager.go +++ b/cmd/manager/manager/manager.go @@ -24,10 +24,10 @@ import ( "strings" "time" - "github.com/kubernetes/deployment-manager/common" - "github.com/kubernetes/deployment-manager/manager/repository" - "github.com/kubernetes/deployment-manager/registry" - "github.com/kubernetes/deployment-manager/util" + "github.com/kubernetes/deployment-manager/cmd/manager/repository" + "github.com/kubernetes/deployment-manager/pkg/common" + "github.com/kubernetes/deployment-manager/pkg/registry" + "github.com/kubernetes/deployment-manager/pkg/util" ) // Manager manages a persistent set of Deployments. diff --git a/manager/manager/manager_test.go b/cmd/manager/manager/manager_test.go similarity index 96% rename from manager/manager/manager_test.go rename to cmd/manager/manager/manager_test.go index 40ebe7f4f..3065f281a 100644 --- a/manager/manager/manager_test.go +++ b/cmd/manager/manager/manager_test.go @@ -22,23 +22,23 @@ import ( "strings" "testing" - "github.com/kubernetes/deployment-manager/common" - "github.com/kubernetes/deployment-manager/registry" + "github.com/kubernetes/deployment-manager/pkg/common" + "github.com/kubernetes/deployment-manager/pkg/registry" ) var template = common.Template{Name: "test", Content: "test"} var layout = common.Layout{ - Resources: []*common.LayoutResource{&common.LayoutResource{Resource: common.Resource{Name: "test", Type: "test"}}}, + Resources: []*common.LayoutResource{{Resource: common.Resource{Name: "test", Type: "test"}}}, } var configuration = common.Configuration{ - Resources: []*common.Resource{&common.Resource{Name: "test", Type: "test"}}, + Resources: []*common.Resource{{Name: "test", Type: "test"}}, } var resourcesWithSuccessState = common.Configuration{ - Resources: []*common.Resource{&common.Resource{Name: "test", Type: "test", State: &common.ResourceState{Status: common.Created}}}, + Resources: []*common.Resource{{Name: "test", Type: "test", State: &common.ResourceState{Status: common.Created}}}, } var resourcesWithFailureState = common.Configuration{ - Resources: []*common.Resource{&common.Resource{ + Resources: []*common.Resource{{ Name: "test", Type: "test", State: &common.ResourceState{ @@ -64,7 +64,7 @@ var deployment = common.Deployment{ var deploymentList = []common.Deployment{deployment, {Name: "test2"}} -var typeInstMap = map[string][]string{"test": []string{"test"}} +var typeInstMap = map[string][]string{"test": {"test"}} var errTest = errors.New("test error") diff --git a/manager/manager/typeresolver.go b/cmd/manager/manager/typeresolver.go similarity index 96% rename from manager/manager/typeresolver.go rename to cmd/manager/manager/typeresolver.go index 52221b3c5..449003fee 100644 --- a/manager/manager/typeresolver.go +++ b/cmd/manager/manager/typeresolver.go @@ -20,9 +20,9 @@ import ( "fmt" "net/http" - "github.com/kubernetes/deployment-manager/common" - "github.com/kubernetes/deployment-manager/registry" - "github.com/kubernetes/deployment-manager/util" + "github.com/kubernetes/deployment-manager/pkg/common" + "github.com/kubernetes/deployment-manager/pkg/registry" + "github.com/kubernetes/deployment-manager/pkg/util" "github.com/ghodss/yaml" ) @@ -180,7 +180,7 @@ func (tr *typeResolver) ResolveTypes(config *common.Configuration, imports []*co for _, u := range urls { if len(fetched[u]) == 0 { // If this import URL is new to us, add it to the URLs to fetch. - toFetch = append(toFetch, &fetchUnit{[]fetchableURL{fetchableURL{urlRegistry, u}}}) + toFetch = append(toFetch, &fetchUnit{[]fetchableURL{{urlRegistry, u}}}) } else { // If this is not a new import URL and we've already fetched its contents, // reuse them. Also, check if we also found a schema for that import URL and diff --git a/manager/manager/typeresolver_test.go b/cmd/manager/manager/typeresolver_test.go similarity index 61% rename from manager/manager/typeresolver_test.go rename to cmd/manager/manager/typeresolver_test.go index 0e175a8f7..0c1b1719c 100644 --- a/manager/manager/typeresolver_test.go +++ b/cmd/manager/manager/typeresolver_test.go @@ -24,8 +24,8 @@ import ( "testing" "github.com/ghodss/yaml" - "github.com/kubernetes/deployment-manager/common" - "github.com/kubernetes/deployment-manager/registry" + "github.com/kubernetes/deployment-manager/pkg/common" + "github.com/kubernetes/deployment-manager/pkg/registry" ) type responseAndError struct { @@ -118,7 +118,7 @@ resources: ` func TestIncludedImport(t *testing.T) { - imports := []*common.ImportFile{&common.ImportFile{Name: "foo.py"}} + imports := []*common.ImportFile{{Name: "foo.py"}} test := resolverTestCase{ config: includeImport, imports: imports, @@ -133,11 +133,11 @@ resources: ` func TestSingleUrl(t *testing.T) { - finalImports := []*common.ImportFile{&common.ImportFile{Name: "http://my-fake-url", Path: "http://my-fake-url", Content: "my-content"}} + finalImports := []*common.ImportFile{{Name: "http://my-fake-url", Path: "http://my-fake-url", Content: "my-content"}} responses := map[string]responseAndError{ - "http://my-fake-url": responseAndError{nil, http.StatusOK, "my-content"}, - "http://my-fake-url.schema": responseAndError{nil, http.StatusNotFound, ""}, + "http://my-fake-url": {nil, http.StatusOK, "my-content"}, + "http://my-fake-url.schema": {nil, http.StatusNotFound, ""}, } test := resolverTestCase{ @@ -151,7 +151,7 @@ func TestSingleUrl(t *testing.T) { func TestSingleUrlWith500(t *testing.T) { responses := map[string]responseAndError{ - "http://my-fake-url": responseAndError{nil, http.StatusInternalServerError, "my-content"}, + "http://my-fake-url": {nil, http.StatusInternalServerError, "my-content"}, } test := resolverTestCase{ @@ -171,16 +171,16 @@ imports: func TestSingleUrlWithSchema(t *testing.T) { finalImports := []*common.ImportFile{ - &common.ImportFile{Name: "http://my-fake-url", Path: "http://my-fake-url", Content: "my-content"}, - &common.ImportFile{Name: "schema-import", Content: "schema-import"}, - &common.ImportFile{Name: "http://my-fake-url.schema", Content: schema1}, + {Name: "http://my-fake-url", Path: "http://my-fake-url", Content: "my-content"}, + {Name: "schema-import", Content: "schema-import"}, + {Name: "http://my-fake-url.schema", Content: schema1}, } responses := map[string]responseAndError{ - "http://my-fake-url": responseAndError{nil, http.StatusOK, "my-content"}, - "http://my-fake-url.schema": responseAndError{nil, http.StatusOK, schema1}, - "my-next-url": responseAndError{nil, http.StatusOK, "schema-import"}, - "my-next-url.schema": responseAndError{nil, http.StatusNotFound, ""}, + "http://my-fake-url": {nil, http.StatusOK, "my-content"}, + "http://my-fake-url.schema": {nil, http.StatusOK, schema1}, + "my-next-url": {nil, http.StatusOK, "schema-import"}, + "my-next-url.schema": {nil, http.StatusNotFound, ""}, } test := resolverTestCase{ @@ -210,18 +210,18 @@ resources: func TestTooManyImports(t *testing.T) { responses := map[string]responseAndError{ - "http://my-fake-url": responseAndError{nil, http.StatusOK, "my-content"}, - "http://my-fake-url.schema": responseAndError{nil, http.StatusNotFound, ""}, - "http://my-fake-url1": responseAndError{nil, http.StatusOK, "my-content"}, - "http://my-fake-url1.schema": responseAndError{nil, http.StatusNotFound, ""}, - "http://my-fake-url2": responseAndError{nil, http.StatusOK, "my-content"}, - "http://my-fake-url2.schema": responseAndError{nil, http.StatusNotFound, ""}, - "http://my-fake-url3": responseAndError{nil, http.StatusOK, "my-content"}, - "http://my-fake-url3.schema": responseAndError{nil, http.StatusNotFound, ""}, - "http://my-fake-url4": responseAndError{nil, http.StatusOK, "my-content"}, - "http://my-fake-url4.schema": responseAndError{nil, http.StatusNotFound, ""}, - "http://my-fake-url5": responseAndError{nil, http.StatusOK, "my-content"}, - "http://my-fake-url5.schema": responseAndError{nil, http.StatusNotFound, ""}, + "http://my-fake-url": {nil, http.StatusOK, "my-content"}, + "http://my-fake-url.schema": {nil, http.StatusNotFound, ""}, + "http://my-fake-url1": {nil, http.StatusOK, "my-content"}, + "http://my-fake-url1.schema": {nil, http.StatusNotFound, ""}, + "http://my-fake-url2": {nil, http.StatusOK, "my-content"}, + "http://my-fake-url2.schema": {nil, http.StatusNotFound, ""}, + "http://my-fake-url3": {nil, http.StatusOK, "my-content"}, + "http://my-fake-url3.schema": {nil, http.StatusNotFound, ""}, + "http://my-fake-url4": {nil, http.StatusOK, "my-content"}, + "http://my-fake-url4.schema": {nil, http.StatusNotFound, ""}, + "http://my-fake-url5": {nil, http.StatusOK, "my-content"}, + "http://my-fake-url5.schema": {nil, http.StatusNotFound, ""}, } test := resolverTestCase{ @@ -250,21 +250,21 @@ imports: func TestSharedImport(t *testing.T) { finalImports := []*common.ImportFile{ - &common.ImportFile{Name: "http://my-fake-url", Path: "http://my-fake-url", Content: "my-content"}, - &common.ImportFile{Name: "http://my-fake-url1", Path: "http://my-fake-url1", Content: "my-content-1"}, - &common.ImportFile{Name: "schema-import", Content: "schema-import"}, - &common.ImportFile{Name: "schema-import-1", Content: "schema-import"}, - &common.ImportFile{Name: "http://my-fake-url.schema", Content: schema1}, - &common.ImportFile{Name: "http://my-fake-url1.schema", Content: schema2}, + {Name: "http://my-fake-url", Path: "http://my-fake-url", Content: "my-content"}, + {Name: "http://my-fake-url1", Path: "http://my-fake-url1", Content: "my-content-1"}, + {Name: "schema-import", Content: "schema-import"}, + {Name: "schema-import-1", Content: "schema-import"}, + {Name: "http://my-fake-url.schema", Content: schema1}, + {Name: "http://my-fake-url1.schema", Content: schema2}, } responses := map[string]responseAndError{ - "http://my-fake-url": responseAndError{nil, http.StatusOK, "my-content"}, - "http://my-fake-url.schema": responseAndError{nil, http.StatusOK, schema1}, - "http://my-fake-url1": responseAndError{nil, http.StatusOK, "my-content-1"}, - "http://my-fake-url1.schema": responseAndError{nil, http.StatusOK, schema2}, - "my-next-url": responseAndError{nil, http.StatusOK, "schema-import"}, - "my-next-url.schema": responseAndError{nil, http.StatusNotFound, ""}, + "http://my-fake-url": {nil, http.StatusOK, "my-content"}, + "http://my-fake-url.schema": {nil, http.StatusOK, schema1}, + "http://my-fake-url1": {nil, http.StatusOK, "my-content-1"}, + "http://my-fake-url1.schema": {nil, http.StatusOK, schema2}, + "my-next-url": {nil, http.StatusOK, "schema-import"}, + "my-next-url.schema": {nil, http.StatusNotFound, ""}, } test := resolverTestCase{ @@ -287,31 +287,31 @@ resources: func TestShortGithubUrl(t *testing.T) { finalImports := []*common.ImportFile{ - &common.ImportFile{ + { Name: "github.com/kubernetes/application-dm-templates/common/replicatedservice:v1", Path: "https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v1/replicatedservice.py", Content: "my-content"}, - &common.ImportFile{ + { Name: "github.com/kubernetes/application-dm-templates/common/replicatedservice:v2", Path: "https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v2/replicatedservice.py", Content: "my-content-2"}, } downloadResponses := map[string]registry.DownloadResponse{ - "https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v1/replicatedservice.py": registry.DownloadResponse{Err: nil, Code: http.StatusOK, Body: "my-content"}, - "https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v1/replicatedservice.py.schema": registry.DownloadResponse{Err: nil, Code: http.StatusNotFound, Body: ""}, - "https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v2/replicatedservice.py": registry.DownloadResponse{Err: nil, Code: http.StatusOK, Body: "my-content-2"}, - "https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v2/replicatedservice.py.schema": registry.DownloadResponse{Err: nil, Code: http.StatusNotFound, Body: ""}, + "https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v1/replicatedservice.py": {Err: nil, Code: http.StatusOK, Body: "my-content"}, + "https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v1/replicatedservice.py.schema": {Err: nil, Code: http.StatusNotFound, Body: ""}, + "https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v2/replicatedservice.py": {Err: nil, Code: http.StatusOK, Body: "my-content-2"}, + "https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v2/replicatedservice.py.schema": {Err: nil, Code: http.StatusNotFound, Body: ""}, } githubURLMaps := map[registry.Type]registry.TestURLAndError{ - registry.NewTypeOrDie("common", "replicatedservice", "v1"): registry.TestURLAndError{URL: "https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v1/replicatedservice.py", Err: nil}, - registry.NewTypeOrDie("common", "replicatedservice", "v2"): registry.TestURLAndError{URL: "https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v2/replicatedservice.py", Err: nil}, + registry.NewTypeOrDie("common", "replicatedservice", "v1"): {URL: "https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v1/replicatedservice.py", Err: nil}, + registry.NewTypeOrDie("common", "replicatedservice", "v2"): {URL: "https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v2/replicatedservice.py", Err: nil}, } gcsURLMaps := map[registry.Type]registry.TestURLAndError{ - registry.NewTypeOrDie("common", "replicatedservice", "v1"): registry.TestURLAndError{URL: "https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v1/replicatedservice.py", Err: nil}, - registry.NewTypeOrDie("common", "replicatedservice", "v2"): registry.TestURLAndError{URL: "https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v2/replicatedservice.py", Err: nil}, + registry.NewTypeOrDie("common", "replicatedservice", "v1"): {URL: "https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v1/replicatedservice.py", Err: nil}, + registry.NewTypeOrDie("common", "replicatedservice", "v2"): {URL: "https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v2/replicatedservice.py", Err: nil}, } grp := registry.NewTestGithubRegistryProviderWithDownloads("github.com/kubernetes/application-dm-templates", githubURLMaps, downloadResponses) diff --git a/manager/repository/persistent/persistent.go b/cmd/manager/repository/persistent/persistent.go similarity index 99% rename from manager/repository/persistent/persistent.go rename to cmd/manager/repository/persistent/persistent.go index fadf1285a..f5a9e0ca9 100644 --- a/manager/repository/persistent/persistent.go +++ b/cmd/manager/repository/persistent/persistent.go @@ -25,8 +25,8 @@ import ( "os" "time" - "github.com/kubernetes/deployment-manager/common" - "github.com/kubernetes/deployment-manager/manager/repository" + "github.com/kubernetes/deployment-manager/cmd/manager/repository" + "github.com/kubernetes/deployment-manager/pkg/common" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" diff --git a/manager/repository/persistent/persistent_test.go b/cmd/manager/repository/persistent/persistent_test.go similarity index 97% rename from manager/repository/persistent/persistent_test.go rename to cmd/manager/repository/persistent/persistent_test.go index 47038c76e..00ac70d05 100644 --- a/manager/repository/persistent/persistent_test.go +++ b/cmd/manager/repository/persistent/persistent_test.go @@ -14,7 +14,7 @@ limitations under the License. package persistent import ( - "github.com/kubernetes/deployment-manager/manager/repository" + "github.com/kubernetes/deployment-manager/cmd/manager/repository" "sync" "testing" diff --git a/manager/repository/repository.go b/cmd/manager/repository/repository.go similarity index 97% rename from manager/repository/repository.go rename to cmd/manager/repository/repository.go index d4e70d05b..e9424b1ab 100644 --- a/manager/repository/repository.go +++ b/cmd/manager/repository/repository.go @@ -18,7 +18,7 @@ limitations under the License. package repository import ( - "github.com/kubernetes/deployment-manager/common" + "github.com/kubernetes/deployment-manager/pkg/common" ) // Repository manages storage for all Deployment Manager entities, as well as diff --git a/manager/repository/test_common.go b/cmd/manager/repository/test_common.go similarity index 97% rename from manager/repository/test_common.go rename to cmd/manager/repository/test_common.go index 3d5586172..7f20b7d0c 100644 --- a/manager/repository/test_common.go +++ b/cmd/manager/repository/test_common.go @@ -17,7 +17,7 @@ limitations under the License. package repository import ( - "github.com/kubernetes/deployment-manager/common" + "github.com/kubernetes/deployment-manager/pkg/common" "fmt" "testing" @@ -213,8 +213,8 @@ func TestRepositoryDeleteDeploymentWorksForget(t *testing.T, r Repository) { // TestRepositoryTypeInstances checks that type instances can be listed and retrieved successfully. func TestRepositoryTypeInstances(t *testing.T, r Repository) { d1Map := map[string][]*common.TypeInstance{ - "t1": []*common.TypeInstance{ - &common.TypeInstance{ + "t1": { + { Name: "i1", Type: "t1", Deployment: "d1", @@ -225,8 +225,8 @@ func TestRepositoryTypeInstances(t *testing.T, r Repository) { } d2Map := map[string][]*common.TypeInstance{ - "t2": []*common.TypeInstance{ - &common.TypeInstance{ + "t2": { + { Name: "i2", Type: "t2", Deployment: "d2", @@ -237,8 +237,8 @@ func TestRepositoryTypeInstances(t *testing.T, r Repository) { } d3Map := map[string][]*common.TypeInstance{ - "t2": []*common.TypeInstance{ - &common.TypeInstance{ + "t2": { + { Name: "i3", Type: "t2", Deployment: "d3", diff --git a/manager/repository/transient/transient.go b/cmd/manager/repository/transient/transient.go similarity index 98% rename from manager/repository/transient/transient.go rename to cmd/manager/repository/transient/transient.go index 36b7176f7..4655709c7 100644 --- a/manager/repository/transient/transient.go +++ b/cmd/manager/repository/transient/transient.go @@ -23,8 +23,8 @@ import ( "sync" "time" - "github.com/kubernetes/deployment-manager/common" - "github.com/kubernetes/deployment-manager/manager/repository" + "github.com/kubernetes/deployment-manager/cmd/manager/repository" + "github.com/kubernetes/deployment-manager/pkg/common" ) // deploymentTypeInstanceMap stores type instances mapped by deployment name. diff --git a/manager/repository/transient/transient_test.go b/cmd/manager/repository/transient/transient_test.go similarity index 96% rename from manager/repository/transient/transient_test.go rename to cmd/manager/repository/transient/transient_test.go index 368898eb2..06ca917f3 100644 --- a/manager/repository/transient/transient_test.go +++ b/cmd/manager/repository/transient/transient_test.go @@ -14,7 +14,7 @@ limitations under the License. package transient import ( - "github.com/kubernetes/deployment-manager/manager/repository" + "github.com/kubernetes/deployment-manager/cmd/manager/repository" "testing" ) diff --git a/resourcifier/Dockerfile b/cmd/resourcifier/Dockerfile similarity index 100% rename from resourcifier/Dockerfile rename to cmd/resourcifier/Dockerfile diff --git a/resourcifier/Makefile b/cmd/resourcifier/Makefile similarity index 98% rename from resourcifier/Makefile rename to cmd/resourcifier/Makefile index 9d6eebe1a..1b80a7dca 100644 --- a/resourcifier/Makefile +++ b/cmd/resourcifier/Makefile @@ -21,6 +21,7 @@ include ../include.mk DOCKER_REGISTRY := gcr.io PREFIX := $(DOCKER_REGISTRY)/$(PROJECT) IMAGE := resourcifier +TAG := latest ROOT_DIR := $(abspath ./..) DIR = $(ROOT_DIR) diff --git a/resourcifier/configurations.go b/cmd/resourcifier/configurations.go similarity index 97% rename from resourcifier/configurations.go rename to cmd/resourcifier/configurations.go index 140f5159f..f2d9f93dc 100644 --- a/resourcifier/configurations.go +++ b/cmd/resourcifier/configurations.go @@ -17,9 +17,9 @@ limitations under the License. package main import ( - "github.com/kubernetes/deployment-manager/common" - "github.com/kubernetes/deployment-manager/resourcifier/configurator" - "github.com/kubernetes/deployment-manager/util" + "github.com/kubernetes/deployment-manager/cmd/resourcifier/configurator" + "github.com/kubernetes/deployment-manager/pkg/common" + "github.com/kubernetes/deployment-manager/pkg/util" "encoding/json" "errors" diff --git a/resourcifier/configurator/configurator.go b/cmd/resourcifier/configurator/configurator.go similarity index 98% rename from resourcifier/configurator/configurator.go rename to cmd/resourcifier/configurator/configurator.go index 627c42e5f..25499922e 100644 --- a/resourcifier/configurator/configurator.go +++ b/cmd/resourcifier/configurator/configurator.go @@ -23,8 +23,8 @@ import ( "strings" "github.com/ghodss/yaml" - "github.com/kubernetes/deployment-manager/common" - "github.com/kubernetes/deployment-manager/util" + "github.com/kubernetes/deployment-manager/pkg/common" + "github.com/kubernetes/deployment-manager/pkg/util" ) // Configurator configures a Kubernetes cluster using kubectl. diff --git a/resourcifier/main.go b/cmd/resourcifier/main.go similarity index 94% rename from resourcifier/main.go rename to cmd/resourcifier/main.go index c43b92b04..7d82e983a 100644 --- a/resourcifier/main.go +++ b/cmd/resourcifier/main.go @@ -6,7 +6,7 @@ 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. @@ -17,8 +17,8 @@ limitations under the License. package main import ( - "github.com/kubernetes/deployment-manager/util" - "github.com/kubernetes/deployment-manager/version" + "github.com/kubernetes/deployment-manager/pkg/util" + "github.com/kubernetes/deployment-manager/pkg/version" "flag" "fmt" diff --git a/docs/pushing.md b/docs/pushing.md index 381e7a28b..06c4faf37 100644 --- a/docs/pushing.md +++ b/docs/pushing.md @@ -6,7 +6,7 @@ This details the requirements and steps for doing a DM push. In order to build and push DM, you must: -* be an editor or owner on the GCP project `dm-k8s-prod` +* be an editor or owner on the GCP project `dm-k8s-testing` * have `docker` installed and runnable in your current environment * have `gcloud` installed * have `gsutil` installed @@ -17,7 +17,7 @@ To build and push the service containers: ``` $ cd ${GOPATH}/src/github.com/kubernetes/deployment-manager -$ export PROJECT=dm-k8s-prod +$ export PROJECT=dm-k8s-testing $ make push ``` diff --git a/examples/bootstrap/bootstrap.yaml b/examples/bootstrap/bootstrap.yaml index 4deabeb45..c36d38103 100644 --- a/examples/bootstrap/bootstrap.yaml +++ b/examples/bootstrap/bootstrap.yaml @@ -8,7 +8,7 @@ resources: container_port: 8080 external_service: false replicas: 2 - image: gcr.io/dm-k8s-prod/expandybird:latest + image: gcr.io/dm-k8s-testing/expandybird:latest labels: app: dm - name: resourcifier @@ -20,7 +20,7 @@ resources: container_port: 8080 external_service: false replicas: 2 - image: gcr.io/dm-k8s-prod/resourcifier:latest + image: gcr.io/dm-k8s-testing/resourcifier:latest labels: app: dm - name: manager @@ -32,6 +32,6 @@ resources: container_port: 8080 external_service: false replicas: 1 - image: gcr.io/dm-k8s-prod/manager:latest + image: gcr.io/dm-k8s-testing/manager:latest labels: app: dm diff --git a/examples/wordpress/README.md b/examples/wordpress/README.md index 177ff47c7..12573ba0e 100644 --- a/examples/wordpress/README.md +++ b/examples/wordpress/README.md @@ -42,7 +42,7 @@ The template contains the following variables: ``` {% set PROPERTIES = properties or {} %} -{% set PROJECT = PROPERTIES['project'] or 'dm-k8s-prod' %} +{% set PROJECT = PROPERTIES['project'] or 'dm-k8s-testing' %} {% set NFS_SERVER = PROPERTIES['nfs-server'] or {} %} {% set NFS_SERVER_IP = NFS_SERVER['ip'] or '10.0.253.247' %} {% set NFS_SERVER_PORT = NFS_SERVER['port'] or 2049 %} diff --git a/examples/wordpress/wordpress.jinja b/examples/wordpress/wordpress.jinja index 5855b2e8c..c3789b555 100644 --- a/examples/wordpress/wordpress.jinja +++ b/examples/wordpress/wordpress.jinja @@ -1,5 +1,5 @@ {% set PROPERTIES = properties or {} %} -{% set PROJECT = PROPERTIES['project'] or 'dm-k8s-prod' %} +{% set PROJECT = PROPERTIES['project'] or 'dm-k8s-testing' %} {% set NFS_SERVER = PROPERTIES['nfs-server'] or {} %} {% set NFS_SERVER_IP = NFS_SERVER['ip'] or '10.0.253.247' %} {% set NFS_SERVER_PORT = NFS_SERVER['port'] or 2049 %} diff --git a/examples/wordpress/wordpress.jinja.schema b/examples/wordpress/wordpress.jinja.schema index 5b4a8bc21..215b47e1e 100644 --- a/examples/wordpress/wordpress.jinja.schema +++ b/examples/wordpress/wordpress.jinja.schema @@ -8,7 +8,7 @@ info: properties: project: type: string - default: dm-k8s-prod + default: dm-k8s-testing description: Project location to load the images from. nfs-service: type: object diff --git a/expandybird/expansion/expansion.py b/expansion/expansion.py similarity index 100% rename from expandybird/expansion/expansion.py rename to expansion/expansion.py diff --git a/expandybird/expansion/expansion_test.py b/expansion/expansion_test.py similarity index 100% rename from expandybird/expansion/expansion_test.py rename to expansion/expansion_test.py diff --git a/expandybird/expansion/file_expander.py b/expansion/file_expander.py similarity index 100% rename from expandybird/expansion/file_expander.py rename to expansion/file_expander.py diff --git a/expandybird/requirements.txt b/expansion/requirements.txt similarity index 100% rename from expandybird/requirements.txt rename to expansion/requirements.txt diff --git a/expandybird/expansion/sandbox_loader.py b/expansion/sandbox_loader.py similarity index 100% rename from expandybird/expansion/sandbox_loader.py rename to expansion/sandbox_loader.py diff --git a/expandybird/expansion/schema_validation.py b/expansion/schema_validation.py similarity index 100% rename from expandybird/expansion/schema_validation.py rename to expansion/schema_validation.py diff --git a/expandybird/expansion/schema_validation_test.py b/expansion/schema_validation_test.py similarity index 100% rename from expandybird/expansion/schema_validation_test.py rename to expansion/schema_validation_test.py diff --git a/expandybird/expansion/schema_validation_utils.py b/expansion/schema_validation_utils.py similarity index 100% rename from expandybird/expansion/schema_validation_utils.py rename to expansion/schema_validation_utils.py diff --git a/get-install.sh b/get-install.sh index df53665ef..be8f34d14 100755 --- a/get-install.sh +++ b/get-install.sh @@ -15,13 +15,11 @@ set -euo pipefail -DEFAULT_TAG=v1.2 -DEFAULT_BINARY=${GOPATH}/bin/dm -DEFAULT_PLATFORM=$(uname | tr '[:upper:]' '[:lower:]') -DEFAULT_ARCH=$(uname -m) +PLATFORM=$(uname | tr '[:upper:]' '[:lower:]') +ARCH=$(uname -m) STORAGE_URL=http://get-dm.storage.googleapis.com -ZIP=dm-${TAG:-DEFAULT_TAG}-${PLATFORM:-DEFAULT_PLATFORM}-${ARCH:-DEFAULT_ARCH}.zip +ZIP=dm-latest-${PLATFORM}-${ARCH}.zip echo "Downloading ${ZIP}..." curl -Ls "${STORAGE_URL}/${ZIP}" -O diff --git a/glide.lock b/glide.lock index 2e98b0206..3e60f4f38 100644 --- a/glide.lock +++ b/glide.lock @@ -1,51 +1,78 @@ -hash: db55a031aaa2f352fa5e9e4fda871039afb80e383a57fc77e4b35114d47cca8a -updated: 2016-01-26T17:30:54.243252416-07:00 +hash: 2d8e32786782b7979a79850cfc489866a74c068e865f433a73ed4f50ef2644e9 +updated: 2016-02-29T11:21:24.093936684-08:00 imports: +- name: github.com/aokoli/goutils + version: 9c37978a95bd5c709a15883b6242714ea6709e64 +- name: github.com/codegangsta/cli + version: a2943485b110df8842045ae0600047f88a3a56a1 - name: github.com/emicklei/go-restful version: b86acf97a74ed7603ac78d012f5535b4d587b156 + subpackages: + - log - name: github.com/ghodss/yaml version: 73d445a93680fa1a78ae23a5839bad48f32ba1ee -- name: github.com/golang/glog - version: 23def4e6c14b4da8ac2ed8007337bc5eb5007998 - name: github.com/golang/protobuf version: 6aaa8d47701fa6cf07e914ec01fde3d4a1fe79c3 + subpackages: + - proto - name: github.com/google/go-github version: b8b4ac742977310ff6e75140a403a38dab109977 subpackages: - - /github + - github - name: github.com/google/go-querystring version: 2a60fc2ba6c19de80291203597d752e9ba58e4c0 + subpackages: + - query - name: github.com/gorilla/context version: 1c83b3eabd45b6d76072b66b746c20815fb2872d - name: github.com/gorilla/handlers version: 8f2758070a82adb7a3ad6b223a0b91878f32d400 - name: github.com/gorilla/mux version: 26a6070f849969ba72b72256e9f14cf519751690 -- name: github.com/gorilla/schema - version: 14c555599c2a4f493c1e13fd1ea6fdf721739028 - name: github.com/Masterminds/semver version: c4f7ef0702f269161a60489ccbbc9f1241ad1265 -- name: github.com/mjibson/appstats - version: 0542d5f0e87ea3a8fa4174322b9532f5d04f9fa8 -- name: golang.org/x/crypto - version: 1f22c0103821b9390939b6776727195525381532 - name: golang.org/x/net version: 04b9de9b512f58addf28c9853d50ebef61c3953e + subpackages: + - context + - context/ctxhttp - name: golang.org/x/oauth2 version: 8a57ed94ffd43444c0879fe75701732a38afc985 -- name: golang.org/x/text - version: 6d3c22c4525a4da167968fa2479be5524d2e8bd0 -- name: google.golang.com/appengine - version: "" - repo: https://google.golang.com/appengine + subpackages: + - google + - internal + - jws + - jwt - name: google.golang.org/api version: 0caa37974a5f5ae67172acf68b4970f7864f994c + subpackages: + - storage/v1 + - gensupport + - googleapi + - googleapi/internal/uritemplates - name: google.golang.org/appengine version: 6bde959377a90acb53366051d7d587bfd7171354 + subpackages: + - urlfetch + - internal + - internal/urlfetch + - internal/app_identity + - internal/modules + - internal/base + - internal/datastore + - internal/log + - internal/remote_api - name: google.golang.org/cloud version: fb10e8da373d97f6ba5e648299a10b3b91f14cd5 -- name: google.golang.org/grpc - version: e29d659177655e589850ba7d3d83f7ce12ef23dd + subpackages: + - compute/metadata + - internal +- name: gopkg.in/mgo.v2 + version: d90005c5262a3463800497ea5a89aed5fe22c886 + subpackages: + - bson + - internal/sasl + - internal/scram - name: gopkg.in/yaml.v2 version: f7716cbe52baa25d2e9b0d0da546fcf909fc16b4 devImports: [] diff --git a/glide.yaml b/glide.yaml index be7d7dc53..4718d06d0 100644 --- a/glide.yaml +++ b/glide.yaml @@ -1,5 +1,8 @@ package: github.com/kubernetes/deployment-manager import: +- package: github.com/Masterminds/semver +- package: github.com/aokoli/goutils +- package: github.com/codegangsta/cli - package: github.com/emicklei/go-restful - package: github.com/ghodss/yaml - package: github.com/google/go-github @@ -9,3 +12,5 @@ import: - package: github.com/gorilla/mux - package: gopkg.in/yaml.v2 - package: github.com/Masterminds/semver +ignore: +- google.golang.com/appengine diff --git a/hack/dm-push.sh b/hack/dm-push.sh index 8484f7fe0..00d4a8b1c 100755 --- a/hack/dm-push.sh +++ b/hack/dm-push.sh @@ -17,23 +17,21 @@ # Run this from deployment-manager root to build and push the dm client plus # kubernetes install config into the publicly readable GCS bucket gs://get-dm. # -# Must have EDIT permissions on the dm-k8s-prod GCP project. +# Must have EDIT permissions on the dm-k8s-testing GCP project. set -euo pipefail -DEFAULT_TAG=v1.2 -DEFAULT_BINARY=${GOPATH}/bin/dm -DEFAULT_PLATFORM=$(uname | tr '[:upper:]' '[:lower:]') -DEFAULT_ARCH=$(uname -m) +PLATFORM=$(uname | tr '[:upper:]' '[:lower:]') +ARCH=$(uname -m) STORAGE_BUCKET=gs://get-dm -ZIP=dm-${TAG:-DEFAULT_TAG}-${PLATFORM:-DEFAULT_PLATFORM}-${ARCH:-DEFAULT_ARCH}.zip +ZIP=dm-latest-${PLATFORM}-${ARCH}.zip echo "Building..." make echo "Zipping ${ZIP}..." -zip -j ${ZIP} ${BINARY:-DEFAULT_BINARY} install.yaml +zip -j ${ZIP} ${GOPATH}/bin/dm install.yaml echo "Uploading ${ZIP} to ${STORAGE_BUCKET}..." gsutil cp ${ZIP} ${STORAGE_BUCKET} diff --git a/include.mk b/include.mk index fca436983..4ae3c4c89 100644 --- a/include.mk +++ b/include.mk @@ -4,29 +4,3 @@ info: @echo "Registry: ${DOCKER_REGISTRY}" @echo "Project: ${PROJECT}" @echo "Image: ${IMAGE}" - -TAG ?= $(shell echo `date +"%s"`_`date +"%N"`) - -.PHONY: test-unit -test-unit: - @echo Running tests... - go test -v ./... - -.PHONY: lint -lint: - @echo Running golint... - golint ./... - @echo ----------------- - -.PHONY: vet -vet: - @echo Running go vet... - go vet ./... - @echo ----------------- - -.PHONY: setup-gotools -setup-gotools: - @echo Installing golint - go get -u github.com/golang/lint/golint - @echo Installing vet - go get -u -v golang.org/x/tools/cmd/vet diff --git a/install.yaml b/install.yaml index 69a21a54e..3d8dc042a 100644 --- a/install.yaml +++ b/install.yaml @@ -58,7 +58,7 @@ spec: spec: containers: - env: [] - image: gcr.io/dm-k8s-prod/expandybird:v1.2 + image: gcr.io/dm-k8s-testing/expandybird:latest name: expandybird ports: - containerPort: 8080 @@ -102,7 +102,7 @@ spec: spec: containers: - env: [] - image: gcr.io/dm-k8s-prod/resourcifier:v1.2 + image: gcr.io/dm-k8s-testing/resourcifier:latest imagePullPolicy: Always livenessProbe: httpGet: @@ -153,7 +153,7 @@ spec: spec: containers: - env: [] - image: gcr.io/dm-k8s-prod/manager:v1.2 + image: gcr.io/dm-k8s-testing/manager:latest imagePullPolicy: Always livenessProbe: httpGet: diff --git a/chart/chart.go b/pkg/chart/chart.go similarity index 99% rename from chart/chart.go rename to pkg/chart/chart.go index a7b3b4cee..98ccd2c0a 100644 --- a/chart/chart.go +++ b/pkg/chart/chart.go @@ -28,7 +28,7 @@ import ( "path/filepath" "strings" - "github.com/kubernetes/deployment-manager/log" + "github.com/kubernetes/deployment-manager/pkg/log" ) // ChartfileName is the default Chart file name. diff --git a/chart/chart_test.go b/pkg/chart/chart_test.go similarity index 98% rename from chart/chart_test.go rename to pkg/chart/chart_test.go index 88a1815a5..8ef4bf682 100644 --- a/chart/chart_test.go +++ b/pkg/chart/chart_test.go @@ -21,7 +21,7 @@ import ( "path/filepath" "testing" - "github.com/kubernetes/deployment-manager/log" + "github.com/kubernetes/deployment-manager/pkg/log" ) const ( diff --git a/chart/chartfile.go b/pkg/chart/chartfile.go similarity index 100% rename from chart/chartfile.go rename to pkg/chart/chartfile.go diff --git a/chart/chartfile_test.go b/pkg/chart/chartfile_test.go similarity index 100% rename from chart/chartfile_test.go rename to pkg/chart/chartfile_test.go diff --git a/chart/doc.go b/pkg/chart/doc.go similarity index 100% rename from chart/doc.go rename to pkg/chart/doc.go diff --git a/chart/locator.go b/pkg/chart/locator.go similarity index 100% rename from chart/locator.go rename to pkg/chart/locator.go diff --git a/chart/locator_test.go b/pkg/chart/locator_test.go similarity index 92% rename from chart/locator_test.go rename to pkg/chart/locator_test.go index cf87d6eb4..67bfcf751 100644 --- a/chart/locator_test.go +++ b/pkg/chart/locator_test.go @@ -22,9 +22,9 @@ import ( func TestParse(t *testing.T) { tests := map[string]Locator{ - "helm:host/bucket/name#1.2.3": Locator{Scheme: "helm", Host: "host", Bucket: "bucket", Name: "name", Version: "1.2.3"}, - "https://host/bucket/name-1.2.3.tgz": Locator{Scheme: "https", Host: "host", Bucket: "bucket", Name: "name", Version: "1.2.3"}, - "http://host/bucket/name-1.2.3.tgz": Locator{Scheme: "http", Host: "host", Bucket: "bucket", Name: "name", Version: "1.2.3"}, + "helm:host/bucket/name#1.2.3": {Scheme: "helm", Host: "host", Bucket: "bucket", Name: "name", Version: "1.2.3"}, + "https://host/bucket/name-1.2.3.tgz": {Scheme: "https", Host: "host", Bucket: "bucket", Name: "name", Version: "1.2.3"}, + "http://host/bucket/name-1.2.3.tgz": {Scheme: "http", Host: "host", Bucket: "bucket", Name: "name", Version: "1.2.3"}, } for start, expect := range tests { diff --git a/chart/save.go b/pkg/chart/save.go similarity index 98% rename from chart/save.go rename to pkg/chart/save.go index 9d4302e14..8bc815fd6 100644 --- a/chart/save.go +++ b/pkg/chart/save.go @@ -24,7 +24,7 @@ import ( "os" "path/filepath" - "github.com/kubernetes/deployment-manager/log" + "github.com/kubernetes/deployment-manager/pkg/log" ) // Save creates an archived chart to the given directory. diff --git a/chart/save_test.go b/pkg/chart/save_test.go similarity index 100% rename from chart/save_test.go rename to pkg/chart/save_test.go diff --git a/chart/testdata/README.md b/pkg/chart/testdata/README.md similarity index 100% rename from chart/testdata/README.md rename to pkg/chart/testdata/README.md diff --git a/chart/testdata/frobnitz-0.0.1.tgz b/pkg/chart/testdata/frobnitz-0.0.1.tgz similarity index 100% rename from chart/testdata/frobnitz-0.0.1.tgz rename to pkg/chart/testdata/frobnitz-0.0.1.tgz diff --git a/chart/testdata/frobnitz/Chart.yaml b/pkg/chart/testdata/frobnitz/Chart.yaml similarity index 100% rename from chart/testdata/frobnitz/Chart.yaml rename to pkg/chart/testdata/frobnitz/Chart.yaml diff --git a/chart/testdata/frobnitz/LICENSE b/pkg/chart/testdata/frobnitz/LICENSE similarity index 100% rename from chart/testdata/frobnitz/LICENSE rename to pkg/chart/testdata/frobnitz/LICENSE diff --git a/chart/testdata/frobnitz/README.md b/pkg/chart/testdata/frobnitz/README.md similarity index 100% rename from chart/testdata/frobnitz/README.md rename to pkg/chart/testdata/frobnitz/README.md diff --git a/chart/testdata/frobnitz/docs/README.md b/pkg/chart/testdata/frobnitz/docs/README.md similarity index 100% rename from chart/testdata/frobnitz/docs/README.md rename to pkg/chart/testdata/frobnitz/docs/README.md diff --git a/chart/testdata/frobnitz/hooks/pre-install.py b/pkg/chart/testdata/frobnitz/hooks/pre-install.py similarity index 100% rename from chart/testdata/frobnitz/hooks/pre-install.py rename to pkg/chart/testdata/frobnitz/hooks/pre-install.py diff --git a/chart/testdata/frobnitz/icon.svg b/pkg/chart/testdata/frobnitz/icon.svg similarity index 100% rename from chart/testdata/frobnitz/icon.svg rename to pkg/chart/testdata/frobnitz/icon.svg diff --git a/chart/testdata/frobnitz/templates/wordpress-resources.yaml b/pkg/chart/testdata/frobnitz/templates/wordpress-resources.yaml similarity index 100% rename from chart/testdata/frobnitz/templates/wordpress-resources.yaml rename to pkg/chart/testdata/frobnitz/templates/wordpress-resources.yaml diff --git a/chart/testdata/frobnitz/templates/wordpress.jinja b/pkg/chart/testdata/frobnitz/templates/wordpress.jinja similarity index 97% rename from chart/testdata/frobnitz/templates/wordpress.jinja rename to pkg/chart/testdata/frobnitz/templates/wordpress.jinja index 62269a899..f34e4fec9 100644 --- a/chart/testdata/frobnitz/templates/wordpress.jinja +++ b/pkg/chart/testdata/frobnitz/templates/wordpress.jinja @@ -1,6 +1,6 @@ #helm:generate dm_template {% set PROPERTIES = properties or {} %} -{% set PROJECT = PROPERTIES['project'] or 'dm-k8s-prod' %} +{% set PROJECT = PROPERTIES['project'] or 'dm-k8s-testing' %} {% set NFS_SERVER = PROPERTIES['nfs-server'] or {} %} {% set NFS_SERVER_IP = NFS_SERVER['ip'] or '10.0.253.247' %} {% set NFS_SERVER_PORT = NFS_SERVER['port'] or 2049 %} diff --git a/chart/testdata/ill/templates/wordpress.jinja.schema b/pkg/chart/testdata/frobnitz/templates/wordpress.jinja.schema similarity index 98% rename from chart/testdata/ill/templates/wordpress.jinja.schema rename to pkg/chart/testdata/frobnitz/templates/wordpress.jinja.schema index 5b4a8bc21..215b47e1e 100644 --- a/chart/testdata/ill/templates/wordpress.jinja.schema +++ b/pkg/chart/testdata/frobnitz/templates/wordpress.jinja.schema @@ -8,7 +8,7 @@ info: properties: project: type: string - default: dm-k8s-prod + default: dm-k8s-testing description: Project location to load the images from. nfs-service: type: object diff --git a/chart/testdata/frobnitz/templates/wordpress.yaml b/pkg/chart/testdata/frobnitz/templates/wordpress.yaml similarity index 100% rename from chart/testdata/frobnitz/templates/wordpress.yaml rename to pkg/chart/testdata/frobnitz/templates/wordpress.yaml diff --git a/chart/testdata/ill-1.2.3.tgz b/pkg/chart/testdata/ill-1.2.3.tgz similarity index 100% rename from chart/testdata/ill-1.2.3.tgz rename to pkg/chart/testdata/ill-1.2.3.tgz diff --git a/chart/testdata/ill/Chart.yaml b/pkg/chart/testdata/ill/Chart.yaml similarity index 100% rename from chart/testdata/ill/Chart.yaml rename to pkg/chart/testdata/ill/Chart.yaml diff --git a/chart/testdata/ill/LICENSE b/pkg/chart/testdata/ill/LICENSE similarity index 100% rename from chart/testdata/ill/LICENSE rename to pkg/chart/testdata/ill/LICENSE diff --git a/chart/testdata/ill/README.md b/pkg/chart/testdata/ill/README.md similarity index 100% rename from chart/testdata/ill/README.md rename to pkg/chart/testdata/ill/README.md diff --git a/chart/testdata/ill/docs/README.md b/pkg/chart/testdata/ill/docs/README.md similarity index 100% rename from chart/testdata/ill/docs/README.md rename to pkg/chart/testdata/ill/docs/README.md diff --git a/chart/testdata/ill/hooks/pre-install.py b/pkg/chart/testdata/ill/hooks/pre-install.py similarity index 100% rename from chart/testdata/ill/hooks/pre-install.py rename to pkg/chart/testdata/ill/hooks/pre-install.py diff --git a/chart/testdata/ill/templates/wordpress-resources.yaml b/pkg/chart/testdata/ill/templates/wordpress-resources.yaml similarity index 100% rename from chart/testdata/ill/templates/wordpress-resources.yaml rename to pkg/chart/testdata/ill/templates/wordpress-resources.yaml diff --git a/chart/testdata/ill/templates/wordpress.jinja b/pkg/chart/testdata/ill/templates/wordpress.jinja similarity index 97% rename from chart/testdata/ill/templates/wordpress.jinja rename to pkg/chart/testdata/ill/templates/wordpress.jinja index 62269a899..f34e4fec9 100644 --- a/chart/testdata/ill/templates/wordpress.jinja +++ b/pkg/chart/testdata/ill/templates/wordpress.jinja @@ -1,6 +1,6 @@ #helm:generate dm_template {% set PROPERTIES = properties or {} %} -{% set PROJECT = PROPERTIES['project'] or 'dm-k8s-prod' %} +{% set PROJECT = PROPERTIES['project'] or 'dm-k8s-testing' %} {% set NFS_SERVER = PROPERTIES['nfs-server'] or {} %} {% set NFS_SERVER_IP = NFS_SERVER['ip'] or '10.0.253.247' %} {% set NFS_SERVER_PORT = NFS_SERVER['port'] or 2049 %} diff --git a/chart/testdata/frobnitz/templates/wordpress.jinja.schema b/pkg/chart/testdata/ill/templates/wordpress.jinja.schema similarity index 98% rename from chart/testdata/frobnitz/templates/wordpress.jinja.schema rename to pkg/chart/testdata/ill/templates/wordpress.jinja.schema index 5b4a8bc21..215b47e1e 100644 --- a/chart/testdata/frobnitz/templates/wordpress.jinja.schema +++ b/pkg/chart/testdata/ill/templates/wordpress.jinja.schema @@ -8,7 +8,7 @@ info: properties: project: type: string - default: dm-k8s-prod + default: dm-k8s-testing description: Project location to load the images from. nfs-service: type: object diff --git a/chart/testdata/ill/templates/wordpress.yaml b/pkg/chart/testdata/ill/templates/wordpress.yaml similarity index 100% rename from chart/testdata/ill/templates/wordpress.yaml rename to pkg/chart/testdata/ill/templates/wordpress.yaml diff --git a/chart/testdata/nochart.tgz b/pkg/chart/testdata/nochart.tgz similarity index 100% rename from chart/testdata/nochart.tgz rename to pkg/chart/testdata/nochart.tgz diff --git a/chart/testdata/sprocket/Chart.yaml b/pkg/chart/testdata/sprocket/Chart.yaml similarity index 100% rename from chart/testdata/sprocket/Chart.yaml rename to pkg/chart/testdata/sprocket/Chart.yaml diff --git a/chart/testdata/sprocket/LICENSE b/pkg/chart/testdata/sprocket/LICENSE similarity index 100% rename from chart/testdata/sprocket/LICENSE rename to pkg/chart/testdata/sprocket/LICENSE diff --git a/chart/testdata/sprocket/README.md b/pkg/chart/testdata/sprocket/README.md similarity index 100% rename from chart/testdata/sprocket/README.md rename to pkg/chart/testdata/sprocket/README.md diff --git a/chart/testdata/sprocket/docs/README.md b/pkg/chart/testdata/sprocket/docs/README.md similarity index 100% rename from chart/testdata/sprocket/docs/README.md rename to pkg/chart/testdata/sprocket/docs/README.md diff --git a/chart/testdata/sprocket/hooks/pre-install.py b/pkg/chart/testdata/sprocket/hooks/pre-install.py similarity index 100% rename from chart/testdata/sprocket/hooks/pre-install.py rename to pkg/chart/testdata/sprocket/hooks/pre-install.py diff --git a/chart/testdata/sprocket/icon.svg b/pkg/chart/testdata/sprocket/icon.svg similarity index 100% rename from chart/testdata/sprocket/icon.svg rename to pkg/chart/testdata/sprocket/icon.svg diff --git a/chart/testdata/sprocket/templates/placeholder.txt b/pkg/chart/testdata/sprocket/templates/placeholder.txt similarity index 100% rename from chart/testdata/sprocket/templates/placeholder.txt rename to pkg/chart/testdata/sprocket/templates/placeholder.txt diff --git a/common/types.go b/pkg/common/types.go similarity index 100% rename from common/types.go rename to pkg/common/types.go diff --git a/pkg/dm/client.go b/pkg/dm/client.go new file mode 100644 index 000000000..17d207350 --- /dev/null +++ b/pkg/dm/client.go @@ -0,0 +1,270 @@ +package dm + +import ( + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "os" + fancypath "path" + "path/filepath" + "strings" + "time" + + "github.com/kubernetes/deployment-manager/pkg/common" +) + +// The default HTTP timeout +var DefaultHTTPTimeout = time.Second * 10 + +// The default HTTP Protocol +var DefaultHTTPProtocol = "http" + +// Client is a DM client. +type Client struct { + // Timeout on HTTP connections. + HTTPTimeout time.Duration + // The remote host + Host string + // The protocol. Currently only http and https are supported. + Protocol string + // Transport + Transport http.RoundTripper + // Debug enables http logging + Debug bool + + // Base URL for remote service + baseURL *url.URL +} + +// NewClient creates a new DM client. Host name is required. +func NewClient(host string) *Client { + url, _ := DefaultServerURL(host) + + return &Client{ + HTTPTimeout: DefaultHTTPTimeout, + baseURL: url, + Transport: http.DefaultTransport, + } +} + +// SetDebug enables debug mode which logs http +func (c *Client) SetDebug(enable bool) *Client { + c.Debug = enable + return c +} + +// transport wraps client transport if debug is enabled +func (c *Client) transport() http.RoundTripper { + if c.Debug { + return NewDebugTransport(c.Transport) + } + return c.Transport +} + +// SetTransport sets a custom Transport. Defaults to http.DefaultTransport +func (c *Client) SetTransport(tr http.RoundTripper) *Client { + c.Transport = tr + return c +} + +// SetTimeout sets a timeout for http connections +func (c *Client) SetTimeout(seconds int) *Client { + c.HTTPTimeout = time.Duration(time.Duration(seconds) * time.Second) + return c +} + +// url constructs the URL. +func (c *Client) url(rawurl string) (string, error) { + u, err := url.Parse(rawurl) + if err != nil { + return "", err + } + return c.baseURL.ResolveReference(u).String(), nil +} + +func (c *Client) agent() string { + return fmt.Sprintf("helm/%s", "0.0.1") +} + +// CallService is a low-level function for making an API call. +// +// This calls the service and then unmarshals the returned data into dest. +func (c *Client) CallService(path, method, action string, dest interface{}, reader io.ReadCloser) error { + u, err := c.url(path) + if err != nil { + return err + } + + resp, err := c.callHTTP(u, method, action, reader) + if err != nil { + return err + } + if err := json.Unmarshal([]byte(resp), dest); err != nil { + return fmt.Errorf("Failed to parse JSON response from service: %s", resp) + } + return nil +} + +// callHTTP is a low-level primitive for executing HTTP operations. +func (c *Client) callHTTP(path, method, action string, reader io.ReadCloser) (string, error) { + request, err := http.NewRequest(method, path, reader) + + // TODO: dynamically set version + request.Header.Set("User-Agent", c.agent()) + request.Header.Add("Content-Type", "application/json") + + client := &http.Client{ + Timeout: c.HTTPTimeout, + Transport: c.transport(), + } + + response, err := client.Do(request) + if err != nil { + return "", err + } + + defer response.Body.Close() + body, err := ioutil.ReadAll(response.Body) + if err != nil { + return "", err + } + + s := response.StatusCode + if s < http.StatusOK || s >= http.StatusMultipleChoices { + return "", &HTTPError{StatusCode: s, Message: string(body), URL: request.URL} + } + + return string(body), nil +} + +// DefaultServerURL converts a host, host:port, or URL string to the default base server API path +// to use with a Client +func DefaultServerURL(host string) (*url.URL, error) { + if host == "" { + return nil, fmt.Errorf("host must be a URL or a host:port pair") + } + base := host + hostURL, err := url.Parse(base) + if err != nil { + return nil, err + } + if hostURL.Scheme == "" { + hostURL, err = url.Parse(DefaultHTTPProtocol + "://" + base) + if err != nil { + return nil, err + } + } + if len(hostURL.Path) > 0 && !strings.HasSuffix(hostURL.Path, "/") { + hostURL.Path = hostURL.Path + "/" + } + + return hostURL, nil +} + +// ListDeployments lists the deployments in DM. +func (c *Client) ListDeployments() ([]string, error) { + var l []string + if err := c.CallService("deployments", "GET", "list deployments", &l, nil); err != nil { + return nil, err + } + + return l, nil +} + +// PostChart sends a chart to DM for deploying. +// +// This returns the location for the new chart, typically of the form +// `helm:repo/bucket/name-version.tgz`. +func (c *Client) PostChart(filename, deployname string) (string, error) { + f, err := os.Open(filename) + if err != nil { + return "", err + } + + u, err := c.url("/v2/charts") + request, err := http.NewRequest("POST", u, f) + if err != nil { + f.Close() + return "", err + } + + // There is an argument to be made for using the legacy x-octet-stream for + // this. But since we control both sides, we should use the standard one. + // Also, gzip (x-compress) is usually treated as a content encoding. In this + // case it probably is not, but it makes more sense to follow the standard, + // even though we don't assume the remote server will strip it off. + request.Header.Add("Content-Type", "application/x-tar") + request.Header.Add("Content-Encoding", "gzip") + request.Header.Add("X-Deployment-Name", deployname) + request.Header.Add("X-Chart-Name", filepath.Base(filename)) + request.Header.Set("User-Agent", c.agent()) + + client := &http.Client{ + Timeout: c.HTTPTimeout, + Transport: c.transport(), + } + + response, err := client.Do(request) + if err != nil { + return "", err + } + + // We only want 201 CREATED. Admittedly, we could accept 200 and 202. + if response.StatusCode != http.StatusCreated { + body, err := ioutil.ReadAll(response.Body) + response.Body.Close() + if err != nil { + return "", err + } + return "", &HTTPError{StatusCode: response.StatusCode, Message: string(body), URL: request.URL} + } + + loc := response.Header.Get("Location") + return loc, nil +} + +// HTTPError is an error caused by an unexpected HTTP status code. +// +// The StatusCode will not necessarily be a 4xx or 5xx. Any unexpected code +// may be returned. +type HTTPError struct { + StatusCode int + Message string + URL *url.URL +} + +// Error implements the error interface. +func (e *HTTPError) Error() string { + return e.Message +} + +// String implmenets the io.Stringer interface. +func (e *HTTPError) String() string { + return e.Error() +} + +// GetDeployment retrieves the supplied deployment +func (c *Client) GetDeployment(name string) (*common.Deployment, error) { + var deployment *common.Deployment + if err := c.CallService(fancypath.Join("deployments", name), "GET", "get deployment", &deployment, nil); err != nil { + return nil, err + } + return deployment, nil +} + +// DeleteDeployment deletes the supplied deployment +func (c *Client) DeleteDeployment(name string) (*common.Deployment, error) { + var deployment *common.Deployment + if err := c.CallService(filepath.Join("deployments", name), "DELETE", "delete deployment", &deployment, nil); err != nil { + return nil, err + } + return deployment, nil +} + +// PostDeployment posts a deployment objec to the manager service. +func (c *Client) PostDeployment(cfg *common.Configuration) error { + return c.CallService("/deployments", "POST", "post deployment", cfg, nil) +} diff --git a/pkg/dm/client_test.go b/pkg/dm/client_test.go new file mode 100644 index 000000000..e35e99369 --- /dev/null +++ b/pkg/dm/client_test.go @@ -0,0 +1,159 @@ +package dm + +import ( + "fmt" + "net/http" + "net/http/httptest" + "strings" + "testing" + + "github.com/kubernetes/deployment-manager/pkg/common" +) + +func TestDefaultServerURL(t *testing.T) { + tt := []struct { + host string + url string + }{ + {"127.0.0.1", "http://127.0.0.1"}, + {"127.0.0.1:8080", "http://127.0.0.1:8080"}, + {"foo.bar.com", "http://foo.bar.com"}, + {"foo.bar.com/prefix", "http://foo.bar.com/prefix/"}, + {"http://host/prefix", "http://host/prefix/"}, + {"https://host/prefix", "https://host/prefix/"}, + {"http://host", "http://host"}, + {"http://host/other", "http://host/other/"}, + } + + for _, tc := range tt { + u, err := DefaultServerURL(tc.host) + if err != nil { + t.Fatal(err) + } + + if tc.url != u.String() { + t.Errorf("%s, expected host %s, got %s", tc.host, tc.url, u.String()) + } + } +} + +func TestURL(t *testing.T) { + tt := []struct { + host string + path string + url string + }{ + {"127.0.0.1", "foo", "http://127.0.0.1/foo"}, + {"127.0.0.1:8080", "foo", "http://127.0.0.1:8080/foo"}, + {"foo.bar.com", "foo", "http://foo.bar.com/foo"}, + {"foo.bar.com/prefix", "foo", "http://foo.bar.com/prefix/foo"}, + {"http://host/prefix", "foo", "http://host/prefix/foo"}, + {"http://host", "foo", "http://host/foo"}, + {"http://host/other", "/foo", "http://host/foo"}, + } + + for _, tc := range tt { + c := NewClient(tc.host) + p, err := c.url(tc.path) + if err != nil { + t.Fatal(err) + } + + if tc.url != p { + t.Errorf("expected %s, got %s", tc.url, p) + } + } +} + +type fakeClient struct { + *Client + server *httptest.Server + handler http.HandlerFunc +} + +func (c *fakeClient) setup() *fakeClient { + c.server = httptest.NewServer(c.handler) + c.Client = NewClient(c.server.URL) + return c +} + +func (c *fakeClient) teardown() { + c.server.Close() +} + +func TestUserAgent(t *testing.T) { + fc := &fakeClient{ + handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if !strings.HasPrefix(r.UserAgent(), "helm") { + t.Error("user agent is not set") + } + }), + } + fc.setup().ListDeployments() +} + +func TestListDeployments(t *testing.T) { + fc := &fakeClient{ + handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(`["guestbook.yaml"]`)) + }), + } + defer fc.teardown() + + l, err := fc.setup().ListDeployments() + if err != nil { + t.Fatal(err) + } + + if len(l) != 1 { + t.Fatal("expected a single deployment") + } +} + +func TestGetDeployment(t *testing.T) { + fc := &fakeClient{ + handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(`{"name":"guestbook.yaml","id":0,"createdAt":"2016-02-08T12:17:49.251658308-08:00","deployedAt":"2016-02-08T12:17:49.251658589-08:00","modifiedAt":"2016-02-08T12:17:51.177518098-08:00","deletedAt":"0001-01-01T00:00:00Z","state":{"status":"Deployed"},"latestManifest":"manifest-1454962670728402229"}`)) + }), + } + defer fc.teardown() + + d, err := fc.setup().GetDeployment("guestbook.yaml") + if err != nil { + t.Fatal(err) + } + + if d.Name != "guestbook.yaml" { + t.Fatalf("expected deployment name 'guestbook.yaml', got '%s'", d.Name) + } + + if d.State.Status != common.DeployedStatus { + t.Fatalf("expected deployment status 'Deployed', got '%s'", d.State.Status) + } +} + +func TestPostDeployment(t *testing.T) { + cfg := &common.Configuration{ + Resources: []*common.Resource{ + { + Name: "foo", + Type: "helm:example.com/foo/bar", + Properties: map[string]interface{}{ + "port": ":8080", + }, + }, + }, + } + + fc := &fakeClient{ + handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusCreated) + fmt.Fprintln(w, "{}") + }), + } + defer fc.teardown() + + if err := fc.setup().PostDeployment(cfg); err != nil { + t.Fatalf("failed to post deployment: %s", err) + } +} diff --git a/pkg/dm/install.go b/pkg/dm/install.go new file mode 100644 index 000000000..3edb95b4f --- /dev/null +++ b/pkg/dm/install.go @@ -0,0 +1,184 @@ +package dm + +import ( + "github.com/kubernetes/deployment-manager/pkg/format" + "github.com/kubernetes/deployment-manager/pkg/kubectl" +) + +// Install uses kubectl to install the base DM. +// +// Returns the string output received from the operation, and an error if the +// command failed. +func Install(runner kubectl.Runner) (string, error) { + o, err := runner.Create([]byte(InstallYAML)) + return string(o), err +} + +// IsInstalled checks whether DM has been installed. +func IsInstalled(runner kubectl.Runner) bool { + // Basically, we test "all-or-nothing" here: if this returns without error + // we know that we have both the namespace and the manager API server. + out, err := runner.GetByKind("rc", "manager-rc", "dm") + if err != nil { + format.Err("Installation not found: %s %s", out, err) + return false + } + return true +} + +// InstallYAML is the installation YAML for DM. +const InstallYAML = ` +###################################################################### +# Copyright 2015 The Kubernetes Authors All rights reserved. +# 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. +###################################################################### + +--- +apiVersion: v1 +kind: Namespace +metadata: + labels: + app: dm + name: dm-namespace + name: dm +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: dm + name: expandybird-service + name: expandybird-service + namespace: dm +spec: + ports: + - name: expandybird + port: 8081 + targetPort: 8080 + selector: + app: dm + name: expandybird +--- +apiVersion: v1 +kind: ReplicationController +metadata: + labels: + app: dm + name: expandybird-rc + name: expandybird-rc + namespace: dm +spec: + replicas: 2 + selector: + app: dm + name: expandybird + template: + metadata: + labels: + app: dm + name: expandybird + spec: + containers: + - env: [] + image: gcr.io/dm-k8s-testing/expandybird:latest + name: expandybird + ports: + - containerPort: 8080 + name: expandybird +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: dm + name: resourcifier-service + name: resourcifier-service + namespace: dm +spec: + ports: + - name: resourcifier + port: 8082 + targetPort: 8080 + selector: + app: dm + name: resourcifier +--- +apiVersion: v1 +kind: ReplicationController +metadata: + labels: + app: dm + name: resourcifier-rc + name: resourcifier-rc + namespace: dm +spec: + replicas: 2 + selector: + app: dm + name: resourcifier + template: + metadata: + labels: + app: dm + name: resourcifier + spec: + containers: + - env: [] + image: gcr.io/dm-k8s-testing/resourcifier:latest + name: resourcifier + ports: + - containerPort: 8080 + name: resourcifier +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: dm + name: manager-service + name: manager-service + namespace: dm +spec: + ports: + - name: manager + port: 8080 + targetPort: 8080 + selector: + app: dm + name: manager +--- +apiVersion: v1 +kind: ReplicationController +metadata: + labels: + app: dm + name: manager-rc + name: manager-rc + namespace: dm +spec: + replicas: 1 + selector: + app: dm + name: manager + template: + metadata: + labels: + app: dm + name: manager + spec: + containers: + - env: [] + image: gcr.io/dm-k8s-testing/manager:latest + name: manager + ports: + - containerPort: 8080 + name: manager +` diff --git a/pkg/dm/transport.go b/pkg/dm/transport.go new file mode 100644 index 000000000..345cbfa61 --- /dev/null +++ b/pkg/dm/transport.go @@ -0,0 +1,66 @@ +package dm + +import ( + "fmt" + "io" + "net/http" + "net/http/httputil" + "os" +) + +type debugTransport struct { + // Writer is the logging destination + Writer io.Writer + + http.RoundTripper +} + +// NewDebugTransport returns a debugging implementation of a RoundTripper. +func NewDebugTransport(rt http.RoundTripper) http.RoundTripper { + return debugTransport{ + RoundTripper: rt, + Writer: os.Stderr, + } +} + +func (tr debugTransport) CancelRequest(req *http.Request) { + type canceler interface { + CancelRequest(*http.Request) + } + if cr, ok := tr.transport().(canceler); ok { + cr.CancelRequest(req) + } +} + +func (tr debugTransport) RoundTrip(req *http.Request) (*http.Response, error) { + tr.logRequest(req) + resp, err := tr.transport().RoundTrip(req) + if err != nil { + return nil, err + } + tr.logResponse(resp) + return resp, err +} + +func (tr debugTransport) transport() http.RoundTripper { + if tr.RoundTripper != nil { + return tr.RoundTripper + } + return http.DefaultTransport +} + +func (tr debugTransport) logRequest(req *http.Request) { + dump, err := httputil.DumpRequestOut(req, true) + if err != nil { + fmt.Fprintf(tr.Writer, "%s: %s\n", "could not dump request", err) + } + fmt.Fprint(tr.Writer, string(dump)) +} + +func (tr debugTransport) logResponse(resp *http.Response) { + dump, err := httputil.DumpResponse(resp, true) + if err != nil { + fmt.Fprintf(tr.Writer, "%s: %s\n", "could not dump response", err) + } + fmt.Fprint(tr.Writer, string(dump)) +} diff --git a/pkg/dm/transport_test.go b/pkg/dm/transport_test.go new file mode 100644 index 000000000..d563d3eab --- /dev/null +++ b/pkg/dm/transport_test.go @@ -0,0 +1,49 @@ +package dm + +import ( + "bytes" + "net/http" + "net/http/httptest" + "strings" + "testing" +) + +func TestDebugTransport(t *testing.T) { + handler := func(w http.ResponseWriter, req *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write([]byte(`{"status":"awesome"}`)) + } + + server := httptest.NewServer(http.HandlerFunc(handler)) + defer server.Close() + + var output bytes.Buffer + + client := &http.Client{ + Transport: debugTransport{ + Writer: &output, + }, + } + + _, err := client.Get(server.URL) + if err != nil { + t.Fatal(err.Error()) + } + + expected := []string{ + "GET / HTTP/1.1", + "Accept-Encoding: gzip", + "HTTP/1.1 200 OK", + "Content-Length: 20", + "Content-Type: application/json", + `{"status":"awesome"}`, + } + actual := output.String() + + for _, match := range expected { + if !strings.Contains(actual, match) { + t.Errorf("Expected %s to contain %s", actual, match) + } + } +} diff --git a/pkg/dm/uninstall.go b/pkg/dm/uninstall.go new file mode 100644 index 000000000..0acc470cd --- /dev/null +++ b/pkg/dm/uninstall.go @@ -0,0 +1,14 @@ +package dm + +import ( + "github.com/kubernetes/deployment-manager/pkg/kubectl" +) + +// Uninstall uses kubectl to uninstall the base DM. +// +// Returns the string output received from the operation, and an error if the +// command failed. +func Uninstall(runner kubectl.Runner) (string, error) { + o, err := runner.Delete("dm", "Namespace") + return string(o), err +} diff --git a/pkg/doc.go b/pkg/doc.go new file mode 100644 index 000000000..9d78a47aa --- /dev/null +++ b/pkg/doc.go @@ -0,0 +1,2 @@ +// Package pkg contains all libraries for Deployment Manager +package pkg diff --git a/pkg/format/messages.go b/pkg/format/messages.go new file mode 100644 index 000000000..9576e0aad --- /dev/null +++ b/pkg/format/messages.go @@ -0,0 +1,50 @@ +package format + +import ( + "fmt" + "os" + + "github.com/ghodss/yaml" +) + +// This is all just placeholder. + +// Err prints an error message to Stderr. +func Err(msg string, v ...interface{}) { + msg = "[ERROR] " + msg + "\n" + fmt.Fprintf(os.Stderr, msg, v...) +} + +// Info prints an informational message to Stdout. +func Info(msg string, v ...interface{}) { + msg = "[INFO] " + msg + "\n" + fmt.Fprintf(os.Stdout, msg, v...) +} + +// Msg prints a raw message to Stdout. +func Msg(msg string, v ...interface{}) { + fmt.Fprintf(os.Stdout, msg, v...) +} + +// Success is an achievement marked by pretty output. +func Success(msg string, v ...interface{}) { + msg = "[Success] " + msg + "\n" + fmt.Fprintf(os.Stdout, msg, v...) +} + +// Warning emits a warning message. +func Warning(msg string, v ...interface{}) { + msg = "[Warning] " + msg + "\n" + fmt.Fprintf(os.Stdout, msg, v...) +} + +// YAML prints an object in YAML format. +func YAML(v interface{}) error { + y, err := yaml.Marshal(v) + if err != nil { + return fmt.Errorf("Failed to serialize to yaml: %s", v.(string)) + } + + Msg(string(y)) + return nil +} diff --git a/pkg/kubectl/cluster_info.go b/pkg/kubectl/cluster_info.go new file mode 100644 index 000000000..9449319c0 --- /dev/null +++ b/pkg/kubectl/cluster_info.go @@ -0,0 +1,12 @@ +package kubectl + +// ClusterInfo returns Kubernetes cluster info +func (r RealRunner) ClusterInfo() ([]byte, error) { + return command("cluster-info").CombinedOutput() +} + +// ClusterInfo returns the commands to kubectl +func (r PrintRunner) ClusterInfo() ([]byte, error) { + cmd := command("cluster-info") + return []byte(cmd.String()), nil +} diff --git a/pkg/kubectl/command.go b/pkg/kubectl/command.go new file mode 100644 index 000000000..b36e0ad33 --- /dev/null +++ b/pkg/kubectl/command.go @@ -0,0 +1,32 @@ +package kubectl + +import ( + "bytes" + "fmt" + "io/ioutil" + "os/exec" + "strings" +) + +type cmd struct { + *exec.Cmd +} + +func command(args ...string) *cmd { + return &cmd{exec.Command(Path, args...)} +} + +func assignStdin(cmd *cmd, in []byte) { + cmd.Stdin = bytes.NewBuffer(in) +} + +func (c *cmd) String() string { + var stdin string + + if c.Stdin != nil { + b, _ := ioutil.ReadAll(c.Stdin) + stdin = fmt.Sprintf("< %s", string(b)) + } + + return fmt.Sprintf("[CMD] %s %s", strings.Join(c.Args, " "), stdin) +} diff --git a/pkg/kubectl/create.go b/pkg/kubectl/create.go new file mode 100644 index 000000000..af9297aa9 --- /dev/null +++ b/pkg/kubectl/create.go @@ -0,0 +1,21 @@ +package kubectl + +// Create uploads a chart to Kubernetes +func (r RealRunner) Create(stdin []byte) ([]byte, error) { + args := []string{"create", "-f", "-"} + + cmd := command(args...) + assignStdin(cmd, stdin) + + return cmd.CombinedOutput() +} + +// Create returns the commands to kubectl +func (r PrintRunner) Create(stdin []byte) ([]byte, error) { + args := []string{"create", "-f", "-"} + + cmd := command(args...) + assignStdin(cmd, stdin) + + return []byte(cmd.String()), nil +} diff --git a/pkg/kubectl/create_test.go b/pkg/kubectl/create_test.go new file mode 100644 index 000000000..bca94f6e5 --- /dev/null +++ b/pkg/kubectl/create_test.go @@ -0,0 +1,22 @@ +package kubectl + +import ( + "testing" +) + +func TestPrintCreate(t *testing.T) { + var client Runner = PrintRunner{} + + expected := `[CMD] kubectl create -f - < some stdin data` + + out, err := client.Create([]byte("some stdin data")) + if err != nil { + t.Error(err) + } + + actual := string(out) + + if expected != actual { + t.Fatalf("actual %s != expected %s", actual, expected) + } +} diff --git a/pkg/kubectl/delete.go b/pkg/kubectl/delete.go new file mode 100644 index 000000000..52874cfbb --- /dev/null +++ b/pkg/kubectl/delete.go @@ -0,0 +1,18 @@ +package kubectl + +// Delete removes a chart from Kubernetes. +func (r RealRunner) Delete(name, ktype string) ([]byte, error) { + + args := []string{"delete", ktype, name} + + return command(args...).CombinedOutput() +} + +// Delete returns the commands to kubectl +func (r PrintRunner) Delete(name, ktype string) ([]byte, error) { + + args := []string{"delete", ktype, name} + + cmd := command(args...) + return []byte(cmd.String()), nil +} diff --git a/pkg/kubectl/get.go b/pkg/kubectl/get.go new file mode 100644 index 000000000..d80dd385d --- /dev/null +++ b/pkg/kubectl/get.go @@ -0,0 +1,50 @@ +package kubectl + +// Get returns Kubernetes resources +func (r RealRunner) Get(stdin []byte, ns string) ([]byte, error) { + args := []string{"get", "-f", "-"} + + if ns != "" { + args = append([]string{"--namespace=" + ns}, args...) + } + cmd := command(args...) + assignStdin(cmd, stdin) + + return cmd.CombinedOutput() +} + +// GetByKind gets a named thing by kind. +func (r RealRunner) GetByKind(kind, name, ns string) (string, error) { + args := []string{"get", kind, name} + + if ns != "" { + args = append([]string{"--namespace=" + ns}, args...) + } + cmd := command(args...) + o, err := cmd.CombinedOutput() + return string(o), err +} + +// Get returns the commands to kubectl +func (r PrintRunner) Get(stdin []byte, ns string) ([]byte, error) { + args := []string{"get", "-f", "-"} + + if ns != "" { + args = append([]string{"--namespace=" + ns}, args...) + } + cmd := command(args...) + assignStdin(cmd, stdin) + + return []byte(cmd.String()), nil +} + +// GetByKind gets a named thing by kind. +func (r PrintRunner) GetByKind(kind, name, ns string) (string, error) { + args := []string{"get", kind, name} + + if ns != "" { + args = append([]string{"--namespace=" + ns}, args...) + } + cmd := command(args...) + return cmd.String(), nil +} diff --git a/pkg/kubectl/get_test.go b/pkg/kubectl/get_test.go new file mode 100644 index 000000000..532724a20 --- /dev/null +++ b/pkg/kubectl/get_test.go @@ -0,0 +1,17 @@ +package kubectl + +import ( + "testing" +) + +func TestGet(t *testing.T) { + Client = TestRunner{ + out: []byte("running the get command"), + } + + expects := "running the get command" + out, _ := Client.Get([]byte{}, "") + if string(out) != expects { + t.Errorf("%s != %s", string(out), expects) + } +} diff --git a/pkg/kubectl/kubectl.go b/pkg/kubectl/kubectl.go new file mode 100644 index 000000000..a85ca6128 --- /dev/null +++ b/pkg/kubectl/kubectl.go @@ -0,0 +1,32 @@ +package kubectl + +// Path is the path of the kubectl binary +var Path = "kubectl" + +// Runner is an interface to wrap kubectl convenience methods +type Runner interface { + // ClusterInfo returns Kubernetes cluster info + ClusterInfo() ([]byte, error) + // Create uploads a chart to Kubernetes + Create(stdin []byte) ([]byte, error) + // Delete removes a chart from Kubernetes. + Delete(name string, ktype string) ([]byte, error) + // Get returns Kubernetes resources + Get(stdin []byte, ns string) ([]byte, error) + + // GetByKind gets an entry by kind, name, and namespace. + // + // If name is omitted, all entries of that kind are returned. + // + // If NS is omitted, the default NS is assumed. + GetByKind(kind, name, ns string) (string, error) +} + +// RealRunner implements Runner to execute kubectl commands +type RealRunner struct{} + +// PrintRunner implements Runner to return a []byte of the command to be executed +type PrintRunner struct{} + +// Client stores the instance of Runner +var Client Runner = RealRunner{} diff --git a/pkg/kubectl/kubectl_test.go b/pkg/kubectl/kubectl_test.go new file mode 100644 index 000000000..453667330 --- /dev/null +++ b/pkg/kubectl/kubectl_test.go @@ -0,0 +1,12 @@ +package kubectl + +type TestRunner struct { + Runner + + out []byte + err error +} + +func (r TestRunner) Get(stdin []byte, ns string) ([]byte, error) { + return r.out, r.err +} diff --git a/log/log.go b/pkg/log/log.go similarity index 100% rename from log/log.go rename to pkg/log/log.go diff --git a/log/log_test.go b/pkg/log/log_test.go similarity index 100% rename from log/log_test.go rename to pkg/log/log_test.go diff --git a/registry/filebased_credential_provider.go b/pkg/registry/filebased_credential_provider.go similarity index 97% rename from registry/filebased_credential_provider.go rename to pkg/registry/filebased_credential_provider.go index f508717f0..62e436594 100644 --- a/registry/filebased_credential_provider.go +++ b/pkg/registry/filebased_credential_provider.go @@ -22,7 +22,7 @@ import ( "log" "github.com/ghodss/yaml" - "github.com/kubernetes/deployment-manager/common" + "github.com/kubernetes/deployment-manager/pkg/common" ) // FilebasedCredentialProvider provides credentials for registries. diff --git a/registry/filebased_credential_provider_test.go b/pkg/registry/filebased_credential_provider_test.go similarity index 97% rename from registry/filebased_credential_provider_test.go rename to pkg/registry/filebased_credential_provider_test.go index bec6ea542..595463e58 100644 --- a/registry/filebased_credential_provider_test.go +++ b/pkg/registry/filebased_credential_provider_test.go @@ -19,7 +19,7 @@ package registry import ( "testing" - "github.com/kubernetes/deployment-manager/common" + "github.com/kubernetes/deployment-manager/pkg/common" ) var filename = "./test/test_credentials_file.yaml" diff --git a/registry/gcs_registry.go b/pkg/registry/gcs_registry.go similarity index 97% rename from registry/gcs_registry.go rename to pkg/registry/gcs_registry.go index de2ac9d13..471e016ed 100644 --- a/registry/gcs_registry.go +++ b/pkg/registry/gcs_registry.go @@ -17,8 +17,8 @@ limitations under the License. package registry import ( - "github.com/kubernetes/deployment-manager/common" - "github.com/kubernetes/deployment-manager/util" + "github.com/kubernetes/deployment-manager/pkg/common" + "github.com/kubernetes/deployment-manager/pkg/util" // "golang.org/x/net/context" // "golang.org/x/oauth2/google" diff --git a/registry/github_package_registry.go b/pkg/registry/github_package_registry.go similarity index 98% rename from registry/github_package_registry.go rename to pkg/registry/github_package_registry.go index 08eae1d91..f79e489c6 100644 --- a/registry/github_package_registry.go +++ b/pkg/registry/github_package_registry.go @@ -18,7 +18,7 @@ package registry import ( "github.com/google/go-github/github" - "github.com/kubernetes/deployment-manager/common" + "github.com/kubernetes/deployment-manager/pkg/common" "fmt" "log" diff --git a/registry/github_registry.go b/pkg/registry/github_registry.go similarity index 97% rename from registry/github_registry.go rename to pkg/registry/github_registry.go index bb40df620..2e56cd87a 100644 --- a/registry/github_registry.go +++ b/pkg/registry/github_registry.go @@ -18,8 +18,8 @@ package registry import ( "github.com/google/go-github/github" - "github.com/kubernetes/deployment-manager/common" - "github.com/kubernetes/deployment-manager/util" + "github.com/kubernetes/deployment-manager/pkg/common" + "github.com/kubernetes/deployment-manager/pkg/util" "fmt" "net/http" diff --git a/registry/github_template_registry.go b/pkg/registry/github_template_registry.go similarity index 99% rename from registry/github_template_registry.go rename to pkg/registry/github_template_registry.go index dfb20bb9f..1e89efced 100644 --- a/registry/github_template_registry.go +++ b/pkg/registry/github_template_registry.go @@ -18,7 +18,7 @@ package registry import ( "github.com/google/go-github/github" - "github.com/kubernetes/deployment-manager/common" + "github.com/kubernetes/deployment-manager/pkg/common" "fmt" "log" diff --git a/registry/inmem_credential_provider.go b/pkg/registry/inmem_credential_provider.go similarity index 96% rename from registry/inmem_credential_provider.go rename to pkg/registry/inmem_credential_provider.go index d09d5c7fc..843d31231 100644 --- a/registry/inmem_credential_provider.go +++ b/pkg/registry/inmem_credential_provider.go @@ -17,7 +17,7 @@ limitations under the License. package registry import ( - "github.com/kubernetes/deployment-manager/common" + "github.com/kubernetes/deployment-manager/pkg/common" "fmt" ) diff --git a/registry/inmem_credential_provider_test.go b/pkg/registry/inmem_credential_provider_test.go similarity index 97% rename from registry/inmem_credential_provider_test.go rename to pkg/registry/inmem_credential_provider_test.go index 6b650eb05..422021128 100644 --- a/registry/inmem_credential_provider_test.go +++ b/pkg/registry/inmem_credential_provider_test.go @@ -21,7 +21,7 @@ import ( "reflect" "testing" - "github.com/kubernetes/deployment-manager/common" + "github.com/kubernetes/deployment-manager/pkg/common" ) type testCase struct { diff --git a/registry/inmem_registry_service.go b/pkg/registry/inmem_registry_service.go similarity index 97% rename from registry/inmem_registry_service.go rename to pkg/registry/inmem_registry_service.go index c22b802e7..6b9a37ff1 100644 --- a/registry/inmem_registry_service.go +++ b/pkg/registry/inmem_registry_service.go @@ -17,8 +17,8 @@ limitations under the License. package registry import ( - "github.com/kubernetes/deployment-manager/common" - "github.com/kubernetes/deployment-manager/util" + "github.com/kubernetes/deployment-manager/pkg/common" + "github.com/kubernetes/deployment-manager/pkg/util" "fmt" "strings" diff --git a/registry/registry.go b/pkg/registry/registry.go similarity index 97% rename from registry/registry.go rename to pkg/registry/registry.go index f1946269f..2c7358abb 100644 --- a/registry/registry.go +++ b/pkg/registry/registry.go @@ -17,8 +17,8 @@ limitations under the License. package registry import ( - "github.com/kubernetes/deployment-manager/common" - "github.com/kubernetes/deployment-manager/util" + "github.com/kubernetes/deployment-manager/pkg/common" + "github.com/kubernetes/deployment-manager/pkg/util" "fmt" "net/url" diff --git a/registry/registry_test.go b/pkg/registry/registry_test.go similarity index 100% rename from registry/registry_test.go rename to pkg/registry/registry_test.go diff --git a/registry/registryprovider.go b/pkg/registry/registryprovider.go similarity index 98% rename from registry/registryprovider.go rename to pkg/registry/registryprovider.go index d722f4b4c..c1f356c8a 100644 --- a/registry/registryprovider.go +++ b/pkg/registry/registryprovider.go @@ -18,8 +18,8 @@ package registry import ( "github.com/google/go-github/github" - "github.com/kubernetes/deployment-manager/common" - "github.com/kubernetes/deployment-manager/util" + "github.com/kubernetes/deployment-manager/pkg/common" + "github.com/kubernetes/deployment-manager/pkg/util" "golang.org/x/oauth2" "golang.org/x/oauth2/google" storage "google.golang.org/api/storage/v1" @@ -168,7 +168,7 @@ type githubRegistryProvider struct { // NewGithubRegistryProvider creates a GithubRegistryProvider. func NewGithubRegistryProvider(cp common.CredentialProvider) GithubRegistryProvider { if cp == nil { - // TODO: replace this panic with an error return. + // TODO: replace this panic with an error return. panic(fmt.Errorf("no credential provider")) } return &githubRegistryProvider{cp: cp} @@ -240,7 +240,7 @@ type gcsRegistryProvider struct { // NewGCSRegistryProvider creates a GCSRegistryProvider. func NewGCSRegistryProvider(cp common.CredentialProvider) GCSRegistryProvider { if cp == nil { - // TODO: replace this panic with an error return. + // TODO: replace this panic with an error return. panic(fmt.Errorf("no credential provider")) } return &gcsRegistryProvider{cp: cp} diff --git a/registry/registryprovider_test.go b/pkg/registry/registryprovider_test.go similarity index 61% rename from registry/registryprovider_test.go rename to pkg/registry/registryprovider_test.go index bd41b354d..968d51a8a 100644 --- a/registry/registryprovider_test.go +++ b/pkg/registry/registryprovider_test.go @@ -36,13 +36,13 @@ func testURLConversionDriver(rp RegistryProvider, tests map[string]TestURLAndErr func TestShortGithubURLTemplateMapping(t *testing.T) { githubURLMaps := map[Type]TestURLAndError{ - NewTypeOrDie("common", "replicatedservice", "v1"): TestURLAndError{"https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v1/replicatedservice.py", nil}, - NewTypeOrDie("storage", "redis", "v1"): TestURLAndError{"https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/storage/redis/v1/redis.jinja", nil}, + NewTypeOrDie("common", "replicatedservice", "v1"): {"https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v1/replicatedservice.py", nil}, + NewTypeOrDie("storage", "redis", "v1"): {"https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/storage/redis/v1/redis.jinja", nil}, } tests := map[string]TestURLAndError{ - "github.com/kubernetes/application-dm-templates/common/replicatedservice:v1": TestURLAndError{"https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v1/replicatedservice.py", nil}, - "github.com/kubernetes/application-dm-templates/storage/redis:v1": TestURLAndError{"https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/storage/redis/v1/redis.jinja", nil}, + "github.com/kubernetes/application-dm-templates/common/replicatedservice:v1": {"https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v1/replicatedservice.py", nil}, + "github.com/kubernetes/application-dm-templates/storage/redis:v1": {"https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/storage/redis/v1/redis.jinja", nil}, } grp := NewTestGithubRegistryProvider("github.com/kubernetes/application-dm-templates", githubURLMaps) @@ -52,13 +52,13 @@ func TestShortGithubURLTemplateMapping(t *testing.T) { func TestShortGithubURLPackageMapping(t *testing.T) { githubURLMaps := map[Type]TestURLAndError{ - NewTypeOrDie("", "mongodb", ""): TestURLAndError{"https://raw.githubusercontent.com/helm/charts/master/mongodb/manifests/mongodb.yaml", nil}, - NewTypeOrDie("", "redis", ""): TestURLAndError{"https://raw.githubusercontent.com/helm/charts/master/redis/manifests/redis.yaml", nil}, + NewTypeOrDie("", "mongodb", ""): {"https://raw.githubusercontent.com/helm/charts/master/mongodb/manifests/mongodb.yaml", nil}, + NewTypeOrDie("", "redis", ""): {"https://raw.githubusercontent.com/helm/charts/master/redis/manifests/redis.yaml", nil}, } tests := map[string]TestURLAndError{ - "github.com/helm/charts/mongodb": TestURLAndError{"https://raw.githubusercontent.com/helm/charts/master/mongodb/manifests/mongodb.yaml", nil}, - "github.com/helm/charts/redis": TestURLAndError{"https://raw.githubusercontent.com/helm/charts/master/redis/manifests/redis.yaml", nil}, + "github.com/helm/charts/mongodb": {"https://raw.githubusercontent.com/helm/charts/master/mongodb/manifests/mongodb.yaml", nil}, + "github.com/helm/charts/redis": {"https://raw.githubusercontent.com/helm/charts/master/redis/manifests/redis.yaml", nil}, } grp := NewTestGithubRegistryProvider("github.com/helm/charts", githubURLMaps) diff --git a/registry/secrets_credential_provider.go b/pkg/registry/secrets_credential_provider.go similarity index 97% rename from registry/secrets_credential_provider.go rename to pkg/registry/secrets_credential_provider.go index 5ee2f4fd9..54668c529 100644 --- a/registry/secrets_credential_provider.go +++ b/pkg/registry/secrets_credential_provider.go @@ -24,8 +24,8 @@ import ( "log" "github.com/ghodss/yaml" - "github.com/kubernetes/deployment-manager/common" - "github.com/kubernetes/deployment-manager/util" + "github.com/kubernetes/deployment-manager/pkg/common" + "github.com/kubernetes/deployment-manager/pkg/util" ) var ( diff --git a/registry/semver.go b/pkg/registry/semver.go similarity index 100% rename from registry/semver.go rename to pkg/registry/semver.go diff --git a/registry/semver_test.go b/pkg/registry/semver_test.go similarity index 100% rename from registry/semver_test.go rename to pkg/registry/semver_test.go diff --git a/registry/test/test_credentials_file.yaml b/pkg/registry/test/test_credentials_file.yaml similarity index 100% rename from registry/test/test_credentials_file.yaml rename to pkg/registry/test/test_credentials_file.yaml diff --git a/registry/testhelper.go b/pkg/registry/testhelper.go similarity index 97% rename from registry/testhelper.go rename to pkg/registry/testhelper.go index 1df44ce06..76a6e6393 100644 --- a/registry/testhelper.go +++ b/pkg/registry/testhelper.go @@ -22,8 +22,8 @@ import ( "bytes" "io/ioutil" - "github.com/kubernetes/deployment-manager/common" - "github.com/kubernetes/deployment-manager/util" + "github.com/kubernetes/deployment-manager/pkg/common" + "github.com/kubernetes/deployment-manager/pkg/util" "fmt" "net/http" diff --git a/util/httpclient.go b/pkg/util/httpclient.go similarity index 100% rename from util/httpclient.go rename to pkg/util/httpclient.go diff --git a/util/httpclient_test.go b/pkg/util/httpclient_test.go similarity index 99% rename from util/httpclient_test.go rename to pkg/util/httpclient_test.go index c7b7eef46..001ebccc4 100644 --- a/util/httpclient_test.go +++ b/pkg/util/httpclient_test.go @@ -6,7 +6,7 @@ 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. diff --git a/util/httputil.go b/pkg/util/httputil.go similarity index 100% rename from util/httputil.go rename to pkg/util/httputil.go diff --git a/util/kubernetes.go b/pkg/util/kubernetes.go similarity index 100% rename from util/kubernetes.go rename to pkg/util/kubernetes.go diff --git a/util/kubernetes_kubectl.go b/pkg/util/kubernetes_kubectl.go similarity index 100% rename from util/kubernetes_kubectl.go rename to pkg/util/kubernetes_kubectl.go diff --git a/util/kubernetesutil.go b/pkg/util/kubernetesutil.go similarity index 96% rename from util/kubernetesutil.go rename to pkg/util/kubernetesutil.go index 959c6ecae..cbf653217 100644 --- a/util/kubernetesutil.go +++ b/pkg/util/kubernetesutil.go @@ -21,7 +21,7 @@ import ( "time" "github.com/ghodss/yaml" - "github.com/kubernetes/deployment-manager/common" + "github.com/kubernetes/deployment-manager/pkg/common" ) // ParseKubernetesObject parses a Kubernetes API object in YAML format. diff --git a/util/kubernetesutil_test.go b/pkg/util/kubernetesutil_test.go similarity index 98% rename from util/kubernetesutil_test.go rename to pkg/util/kubernetesutil_test.go index d34991a1f..0f1513135 100644 --- a/util/kubernetesutil_test.go +++ b/pkg/util/kubernetesutil_test.go @@ -6,7 +6,7 @@ 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. @@ -23,7 +23,7 @@ import ( "github.com/ghodss/yaml" - "github.com/kubernetes/deployment-manager/common" + "github.com/kubernetes/deployment-manager/pkg/common" ) var serviceInput = ` diff --git a/util/templateutil.go b/pkg/util/templateutil.go similarity index 98% rename from util/templateutil.go rename to pkg/util/templateutil.go index 35f507afd..69d4f04d3 100644 --- a/util/templateutil.go +++ b/pkg/util/templateutil.go @@ -26,7 +26,7 @@ import ( "path/filepath" "github.com/ghodss/yaml" - "github.com/kubernetes/deployment-manager/common" + "github.com/kubernetes/deployment-manager/pkg/common" ) // NewTemplateFromType creates and returns a new template whose content diff --git a/util/templateutil_test.go b/pkg/util/templateutil_test.go similarity index 98% rename from util/templateutil_test.go rename to pkg/util/templateutil_test.go index 36a99c73a..1c5a8784f 100644 --- a/util/templateutil_test.go +++ b/pkg/util/templateutil_test.go @@ -39,7 +39,7 @@ target_port: 8080 container_port: 8080 external_service: true replicas: 3 -image: gcr.io/dm-k8s-prod/expandybird +image: gcr.io/dm-k8s-testing/expandybird labels: app: expandybird ` diff --git a/version/version.go b/pkg/version/version.go similarity index 95% rename from version/version.go rename to pkg/version/version.go index 35b47d089..fa1332c96 100644 --- a/version/version.go +++ b/pkg/version/version.go @@ -6,7 +6,7 @@ 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. @@ -22,4 +22,4 @@ package version // 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. -const DeploymentManagerVersion = "0.0.1" +var DeploymentManagerVersion = "0.0.1" diff --git a/rootfs/README.md b/rootfs/README.md new file mode 100644 index 000000000..161bc9e9f --- /dev/null +++ b/rootfs/README.md @@ -0,0 +1,26 @@ +# RootFS + +This directory stores all files that should be copied to the rootfs of a +Docker container. The files should be stored according to the correct +directory structure of the destination container. For example: + +``` +rootfs/bin -> /bin +rootfs/usr/local/share -> /usr/local/share +``` + +## Dockerfile + +A Dockerfile in the rootfs is used to build the image. Where possible, +compilation should not be done in this Dockerfile, since we are +interested in deploying the smallest possible images. + +Example: + +```Dockerfile +FROM alpine:3.2 + +COPY . / + +ENTRYPOINT ["/usr/local/bin/boot"] +``` diff --git a/rootfs/expandybird/.dockerignore b/rootfs/expandybird/.dockerignore new file mode 100644 index 000000000..f6fb65317 --- /dev/null +++ b/rootfs/expandybird/.dockerignore @@ -0,0 +1,3 @@ +.dockerignore +Dockerfile +Makefile diff --git a/rootfs/expandybird/Dockerfile b/rootfs/expandybird/Dockerfile new file mode 100644 index 000000000..cea99a7cd --- /dev/null +++ b/rootfs/expandybird/Dockerfile @@ -0,0 +1,24 @@ +FROM alpine:3.3 + +COPY . / + +# install common packages +RUN apk add --update-cache curl python + +WORKDIR /opt + +# install pip +RUN curl -sSL https://raw.githubusercontent.com/pypa/pip/7.1.2/contrib/get-pip.py | python - + +# install dependencies +RUN pip install --disable-pip-version-check --no-cache-dir -r /opt/expansion/requirements.txt + +# cleanup. +RUN apk del --purge \ + curl \ + python \ + && rm -rf /var/cache/apk/* + +# define execution environment +CMD ["/bin/expandybird", "-expansion_binary", "/opt/expansion/expansion.py"] +EXPOSE 8000 diff --git a/rootfs/expandybird/Makefile b/rootfs/expandybird/Makefile new file mode 100644 index 000000000..e293f49af --- /dev/null +++ b/rootfs/expandybird/Makefile @@ -0,0 +1,24 @@ +DOCKER_REGISTRY := gcr.io +PREFIX := $(DOCKER_REGISTRY)/$(PROJECT) +IMAGE ?= expandybird +TAG ?= git-$(shell git rev-parse --short HEAD) +FULL_IMAGE := $(PREFIX)/$(IMAGE) + +.PHONY: container +container: binary expansion + docker build -t $(FULL_IMAGE):latest -f Dockerfile . + docker tag $(FULL_IMAGE):latest $(FULL_IMAGE):$(TAG) + +.PHONY: push +push: container +ifeq ($(DOCKER_REGISTRY),gcr.io) + gcloud docker push $(PREFIX)/$(IMAGE):$(TAG) +else + docker push $(PREFIX)/$(IMAGE):$(TAG) +endif + +expansion: + cp -R ../../expansion ./opt + +binary: + cp ../../bin/linux-amd64/expandybird ./bin diff --git a/rootfs/expandybird/bin/.keep b/rootfs/expandybird/bin/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/rootfs/expandybird/opt/.keep b/rootfs/expandybird/opt/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/rootfs/manager/.dockerignore b/rootfs/manager/.dockerignore new file mode 100644 index 000000000..f6fb65317 --- /dev/null +++ b/rootfs/manager/.dockerignore @@ -0,0 +1,3 @@ +.dockerignore +Dockerfile +Makefile diff --git a/rootfs/manager/Dockerfile b/rootfs/manager/Dockerfile new file mode 100644 index 000000000..55bbe6b67 --- /dev/null +++ b/rootfs/manager/Dockerfile @@ -0,0 +1,4 @@ +FROM alpine:3.3 +COPY . / +EXPOSE 8080 +CMD ["/bin/manager", "--kubectl=/bin/kubectl"] diff --git a/rootfs/manager/Makefile b/rootfs/manager/Makefile new file mode 100644 index 000000000..886ca837a --- /dev/null +++ b/rootfs/manager/Makefile @@ -0,0 +1,27 @@ +DOCKER_REGISTRY := gcr.io +PREFIX := $(DOCKER_REGISTRY)/$(PROJECT) +IMAGE ?= manager +TAG ?= git-$(shell git rev-parse --short HEAD) +FULL_IMAGE := $(PREFIX)/$(IMAGE) + +KUBE_VERSION ?= v1.1.7 + +.PHONY: container +container: binary kubectl + docker build -t $(FULL_IMAGE):latest -f Dockerfile . + docker tag $(FULL_IMAGE):latest $(FULL_IMAGE):$(TAG) + +.PHONY: push +push: container +ifeq ($(DOCKER_REGISTRY),gcr.io) + gcloud docker push $(PREFIX)/$(IMAGE):$(TAG) +else + docker push $(PREFIX)/$(IMAGE):$(TAG) +endif + +binary: + cp ../../bin/linux-amd64/manager ./bin + +kubectl: + curl -fsSL -o bin/kubectl https://storage.googleapis.com/kubernetes-release/release/${KUBE_VERSION}/bin/linux/amd64/kubectl + chmod +x bin/kubectl diff --git a/rootfs/manager/bin/.keep b/rootfs/manager/bin/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/rootfs/resourcifer/.dockerignore b/rootfs/resourcifer/.dockerignore new file mode 100644 index 000000000..f6fb65317 --- /dev/null +++ b/rootfs/resourcifer/.dockerignore @@ -0,0 +1,3 @@ +.dockerignore +Dockerfile +Makefile diff --git a/rootfs/resourcifer/Dockerfile b/rootfs/resourcifer/Dockerfile new file mode 100644 index 000000000..fca4437c3 --- /dev/null +++ b/rootfs/resourcifer/Dockerfile @@ -0,0 +1,4 @@ +FROM alpine:3.3 +COPY . / +EXPOSE 8080 +CMD ["/bin/resourcifier", "--kubectl=/bin/kubectl"] diff --git a/rootfs/resourcifer/Makefile b/rootfs/resourcifer/Makefile new file mode 100644 index 000000000..56a21da77 --- /dev/null +++ b/rootfs/resourcifer/Makefile @@ -0,0 +1,27 @@ +DOCKER_REGISTRY := gcr.io +PREFIX := $(DOCKER_REGISTRY)/$(PROJECT) +IMAGE ?= resourcifier +TAG ?= git-$(shell git rev-parse --short HEAD) +FULL_IMAGE := $(PREFIX)/$(IMAGE) + +KUBE_VERSION ?= v1.1.7 + +.PHONY: container +container: binary kubectl + docker build -t $(FULL_IMAGE):latest -f Dockerfile . + docker tag $(FULL_IMAGE):latest $(FULL_IMAGE):$(TAG) + +.PHONY: push +push: container +ifeq ($(DOCKER_REGISTRY),gcr.io) + gcloud docker push $(PREFIX)/$(IMAGE):$(TAG) +else + docker push $(PREFIX)/$(IMAGE):$(TAG) +endif + +binary: + cp ../../bin/linux-amd64/resourcifier ./bin + +kubectl: + curl -fsSL -o bin/kubectl https://storage.googleapis.com/kubernetes-release/release/${KUBE_VERSION}/bin/linux/amd64/kubectl + chmod +x bin/kubectl diff --git a/rootfs/resourcifer/bin/.keep b/rootfs/resourcifer/bin/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/scripts/build-go.sh b/scripts/build-go.sh new file mode 100755 index 000000000..b15b1bcd7 --- /dev/null +++ b/scripts/build-go.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +set -o errexit +set -o pipefail + +[[ "$TRACE" ]] && set -x + +readonly REPO=github.com/kubernetes/deployment-manager +readonly DIR="${GOPATH}/src/${REPO}" + +source "${DIR}/scripts/common.sh" + +build_binaries "$@" + +exit 0 diff --git a/scripts/common.sh b/scripts/common.sh new file mode 100644 index 000000000..f1c819213 --- /dev/null +++ b/scripts/common.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash +set -o errexit +set -o pipefail + +readonly ALL_TARGETS=(cmd/dm cmd/expandybird cmd/helm cmd/manager cmd/resourcifier) + +error_exit() { + # Display error message and exit + echo "error: ${1:-"unknown error"}" 1>&2 + exit 1 +} + +assign_version() { + if [[ -z "${VERSION:-}" ]]; then + VERSION=$(version_from_git) + fi +} + +assign_ldflags() { + if [[ -z "${LDFLAGS:-}" ]]; then + LDFLAGS="-s -X ${REPO}/pkg/version.DeploymentManagerVersion=${VERSION}" + fi +} + +version_from_git() { + local git_tag=$(git describe --tags --abbrev=0 2>/dev/null) + local git_commit=$(git rev-parse --short HEAD) + echo "${git_tag}+${git_commit}" +} + +build_binary_cross() { + local target="$1" + + echo "Building ${target}" + gox -verbose \ + -ldflags="${LDFLAGS}" \ + -os="linux darwin" \ + -arch="amd64 386" \ + -output="bin/{{.OS}}-{{.Arch}}/{{.Dir}}" "${REPO}/${target}" +} + +build_binaries() { + local -a targets=($@) + #TODO: accept specific os/arch + local build_cross="${BUILD_CROSS:-}" + + if [[ ${#targets[@]} -eq 0 ]]; then + targets=("${ALL_TARGETS[@]}") + fi + + for t in "${targets[@]}"; do + if [[ -n "$build_cross" ]]; then + build_binary_cross "$t" + else + build_binary "$t" + fi + done +} + +build_binary() { + local target="$1" + local binary="${target##*/}" + local outfile="bin/${binary}" + + echo "Building ${target}" + go build -o "$outfile" -ldflags "$LDFLAGS" "${REPO}/${target}" +}