diff --git a/.gitignore b/.gitignore index f89c8a358862..cd43e4320113 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ vendor/* -!vendor/vendor.json .idea *.iml tools/openapispec/openapispec diff --git a/.travis.yml b/.travis.yml index 7259c6561194..ed1d06be2dd8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,23 +16,16 @@ env: install: - git reset --hard - - ./hack/dockerized make sync + - make sync script: -- ./hack/dockerized make fmt fmt-bash -- if git diff --name-only | grep '.*.go'; then echo "It seems like you did not run - `make fmt fmt-bash`. Please run it and commit the changes"; false; fi -- ./hack/dockerized make generate fmt -- if git diff --name-only | grep 'generated.*.go'; then echo "Content of generated - files changed. Please regenerate and commit them."; false; fi -- if git diff --name-only | grep 'swagger.json' ; then echo "Content of generated - files changed. Please regenerate and commit them." ; false ; fi +- make generate +- if [[ -n "$(git status --porcelain)" ]] ; then echo "It seems like you need to run + `make generate`. Please run it and commit the changes"; false; fi - if diff <(git grep -c '') <(git grep -cI '') | egrep -v 'docs/.*\.png|swagger-ui' | grep '^<'; then echo "Binary files are present in git repostory."; false; fi -- ./hack/dockerized make check -- ./hack/dockerized make build -- if [[ $TRAVIS_REPO_SLUG == "kubevirt/kubevirt" ]]; then ./hack/dockerized make goveralls TRAVIS_JOB_ID=${TRAVIS_JOB_ID} TRAVIS_PULL_REQUEST=${TRAVIS_PULL_REQUEST} TRAVIS_BRANCH=${TRAVIS_BRANCH}; else ./hack/dockerized make test; fi -- ./hack/dockerized make apidocs +- if [[ $TRAVIS_REPO_SLUG == "kubevirt/kubevirt" ]]; then make goveralls TRAVIS_JOB_ID=${TRAVIS_JOB_ID} TRAVIS_PULL_REQUEST=${TRAVIS_PULL_REQUEST} TRAVIS_BRANCH=${TRAVIS_BRANCH}; else make test; fi +- make apidocs - make manifests DOCKER_TAG=$TRAVIS_TAG # falls back to latest if not on a tag cache: diff --git a/Makefile b/Makefile index 1a92fc447326..19cc5ff53687 100644 --- a/Makefile +++ b/Makefile @@ -1,88 +1,47 @@ export GO15VENDOREXPERIMENT := 1 -UNAME := $(shell uname) -ifeq ($(UNAME), Darwin) - HASH := md5 -else - HASH := md5sum -endif - all: build manifests -generate: sync - find pkg/ -name "*generated*.go" -exec rm {} -f \; - ./hack/build-go.sh generate ${WHAT} - goimports -w -local kubevirt.io cmd/ pkg/ tests/ - ./hack/bootstrap-ginkgo.sh - (cd tools/openapispec/ && go build) - tools/openapispec/openapispec --dump-api-spec-path api/openapi-spec/swagger.json +generate: + hack/dockerized "hack/glide-checksync.sh && ./hack/generate.sh" -apidocs: generate - ./hack/gen-swagger-doc/gen-swagger-docs.sh v1 html +apidocs: + hack/dockerized "hack/glide-checksync.sh && ./hack/generate.sh && ./hack/gen-swagger-doc/gen-swagger-docs.sh v1 html" -build: checksync fmt vet compile +build: + hack/dockerized "hack/glide-checksync.sh && ./hack/check.sh && ./hack/build-go.sh install ${WHAT}" goveralls: - ./hack/goveralls.sh - -compile: - ./hack/build-go.sh install ${WHAT} - -vet: - ./hack/build-go.sh vet ${WHAT} - -fmt: - goimports -w -local kubevirt.io cmd/ pkg/ tests/ + hack/dockerized "hack/glide-checksync.sh && ./hack/check.sh && ./hack/build-go.sh install && ./hack/goveralls.sh" -fmt-bash: - shfmt -i 4 -w cluster/ hack/ images/ - -test: build - ./hack/build-go.sh test ${WHAT} +test: + hack/dockerized "hack/glide-checksync.sh && ./hack/check.sh && ./hack/build-go.sh install ${WHAT} && ./hack/build-go.sh test ${WHAT}" functest: - ./hack/functests.sh + hack/functests.sh clean: - ./hack/build-go.sh clean ${WHAT} - rm _out/ -rf + hack/dockerized "./hack/build-go.sh clean ${WHAT} && rm _out/* -rf && rm tools/openapispec/openapispec -rf" rm tools/openapispec/openapispec -rf distclean: clean + hack/dockerized "rm -rf vendor/ && rm -f .glide.*.hash && glide cc" rm -rf vendor/ - rm -f .glide.*.hash - glide cc checksync: - @test -f .glide.yaml.hash || ${HASH} glide.yaml > .glide.yaml.hash - @if [ "`${HASH} glide.yaml`" != "`cat .glide.yaml.hash`" ]; then \ - glide cc; \ - glide update --strip-vendor; \ - ${HASH} glide.yaml > .glide.yaml.hash; \ - ${HASH} glide.lock > .glide.lock.hash; \ - elif [ "`${HASH} glide.lock`" != "`cat .glide.lock.hash`" ]; then \ - make sync; \ - fi + hack/dockerized hack/glide-checksync.sh sync: - glide install --strip-vendor - ${HASH} glide.lock > .glide.lock.hash + hack/dockerized "glide install --strip-vendor && md5sum glide.lock > .glide.lock.hash" -docker: - hack/dockerized make build - ./hack/build-docker.sh build ${WHAT} +docker: build + hack/build-docker.sh build ${WHAT} publish: docker - ./hack/build-docker.sh push ${WHAT} + hack/build-docker.sh push ${WHAT} manifests: - ./hack/build-manifests.sh - -check: check-bash vet - test -z "`./hack/build-go.sh fmt`" - -check-bash: - find . -name \*.sh -exec bash -n \{\} \; + hack/dockerized ./hack/build-manifests.sh .release-functest: make functest > .release-functest 2>&1 @@ -104,4 +63,4 @@ cluster-deploy: cluster-sync: cluster-build cluster-deploy -.PHONY: build fmt test clean distclean checksync sync docker manifests vet publish functest release-announce fmt-bash cluster-up cluster-down cluster-deploy cluster-sync +.PHONY: build test clean distclean checksync sync docker manifests publish functest release-announce cluster-up cluster-down cluster-deploy cluster-sync diff --git a/docs/getting-started.md b/docs/getting-started.md index 88adf3aee808..8d4643a79da6 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -8,46 +8,8 @@ A quick start guide to get KubeVirt up and running inside Vagrant. ## Building -### Dockerized building and code generating - -All go-related make targets can be invoked in an included container. To build -the project within the builder-container, run - -```bash -./hack/dockerized make fmt fmt-bash build -``` - -To generate code, run - -```bash -./hack/dockerized make generate -``` - -If you want to build KubeVirt without docker, read on. - -### Go (1.8 or higher) - -[Go](https://golang.org) needs to be setup to be able to compile the sources. - -**Note:** Go is pretty picky about paths, thus use the suggested ones. - -```bash - # If you haven't set it already, set a GOPATH - echo "export GOPATH=~/go" >> ~/.bashrc - echo "export PATH=\$GOPATH/bin:\$PATH" >> ~/.bashrc - source ~/.bashrc - - mkdir -p ~/go - - sudo dnf install golang - sudo dnf install mercurial -``` - -**Note:** Some code within k8s.io/client-go and k8s.io/apimachinery uses -features from the Go standard libaries introduced in version 1.8. - -If needed, a helpful tool to dynamically manage multiple versions of Go is -[gimme](https://github.com/travis-ci/gimme) +The KubeVirt build system runs completely inside docker. In order to build +KubeVirt you need to have `docker` and `rsync` installed. ### Vagrant @@ -75,36 +37,9 @@ On CentOS/RHEL 7 you might also need to change the libvirt connection string to export LIBVIRT_DEFAULT_URI=qemu:///system ``` -### Build dependencies - -Now we can finally get to the sources, before building KubeVirt we'll need -to install a few build requirements: - -```bash - # We are interfacing with libvirt - sudo dnf install libvirt-devel - - cd $GOPATH - # Use goimports for package import ordering - go get golang.org/x/tools/cmd/goimports - # Setup glide which is used to track dependencies - go get github.com/Masterminds/glide - # Shell script formatter - go get -u mvdan.cc/sh/cmd/shfmt -``` - -### Sources - -Now we can clone the project into your `$GOPATH`: - -```bash - git clone https://github.com/kubevirt/kubevirt.git $GOPATH/src/kubevirt.io/kubevirt - cd $GOPATH/src/kubevirt.io/kubevirt -``` - ### Compile and run it -And finally build all required artifacts and launch the +Build all required artifacts and launch the Vagrant environment: ```bash @@ -143,26 +78,7 @@ You could also run some build steps individually: **Note:** This is only important if you plan to modify sources, you don't need code generators just for building -Currently we use code generators for two purposes: - - * Generating swagger documentation out of struct and field comments for [go-restful](https://github.com/emicklei/go-restful) - * Generating mock interfaces for [gomock](https://github.com/golang/mock) - -So if you add or modify comments on structs in `pkg/api/v1` or if you change -interface definitions, you need to rerun the code generator. - -First install the generator tools: - -```bash -go get -u github.com/golang/mock/gomock -go get -u github.com/rmohr/mock/mockgen -go get -u github.com/rmohr/go-swagger-utils/swagger-doc -go get github.com/onsi/ginkgo/ginkgo -go get -u k8s.io/code-generator/cmd/deepcopy-gen -go get -u k8s.io/code-generator/cmd/defaulter-gen -``` - -Then regenerate the code: +To invoke all code-generators and regenerate generated code, run: ```bash make generate @@ -180,7 +96,7 @@ They don't require vagrant. To run the *functional tests*, make sure you have se up [Vagrant](#vagrant). Then run ```bash - cluster/sync.sh # synchronize with your code, if necessary + make cluster-sync # synchronize with your code, if necessary make functest # run the functional tests against the Vagrant VMs ``` @@ -205,7 +121,6 @@ Finally start a VM called `testvm`: ```bash # This can be done from your GIT repo, no need to log into a vagrant VM - # You might want to watch the Cockpit Cluster topology while running these commands # Create a VM ./cluster/kubectl.sh create -f cluster/vm.yaml @@ -265,7 +180,7 @@ $ ./cluster/kubectl.sh get vms -o json ... ``` -### Accessing the Domain via the VMs SPICE subresource +### Accessing the Domain via VNC First make sure you have `remote-viewer` installed. On Fedora run @@ -281,7 +196,4 @@ cluster/kubectl.sh vnc testvm to start a remote session with `remote-viewer`. -### Accessing the Domain via the VNC primary resource - Since `kubectl` does not support TPR subresources yet, the above `cluster/kubectl.sh vnc` magic is just a wrapper. - diff --git a/hack/bootstrap-ginkgo.sh b/hack/bootstrap-ginkgo.sh index 102ff9169122..7493b996d2e6 100755 --- a/hack/bootstrap-ginkgo.sh +++ b/hack/bootstrap-ginkgo.sh @@ -1,5 +1,11 @@ +#!/bin/bash + +set -e + +source $(dirname "$0")/common.sh + # Find every folder containing tests -for dir in $(find pkg/ -type f -name '*_test.go' -printf '%h\n' | sort -u); do +for dir in $(find ${KUBEVIRT_DIR}/pkg/ -type f -name '*_test.go' -printf '%h\n' | sort -u); do # If there is no file ending with _suite_test.go, bootstrap ginkgo SUITE_FILE=$(find $dir -maxdepth 1 -type f -name '*_suite_test.go') if [ -z "$SUITE_FILE" ]; then diff --git a/hack/build-go.sh b/hack/build-go.sh index a4525be28523..0e3738c09062 100755 --- a/hack/build-go.sh +++ b/hack/build-go.sh @@ -41,16 +41,16 @@ fi if [ $# -eq 0 ]; then if [ "${target}" = "test" ]; then ( - cd pkg + cd ${KUBEVIRT_DIR}/pkg go ${target} -v ./... ) else ( - cd pkg + cd ${KUBEVIRT_DIR}/pkg go $target ./... ) ( - cd tests + cd ${KUBEVIRT_DIR}/tests go $target ./... ) fi @@ -75,6 +75,7 @@ for arg in $args; do mkdir -p ${CMD_OUT_DIR}/${BIN_NAME} ( cd $arg + go vet ./... go build -o ${CMD_OUT_DIR}/${BIN_NAME}/${ARCHBIN} (cd ${CMD_OUT_DIR}/${BIN_NAME} && ln -sf ${ARCHBIN} ${BIN_NAME}) ) diff --git a/hack/check.sh b/hack/check.sh new file mode 100755 index 000000000000..c56ec0c0c05a --- /dev/null +++ b/hack/check.sh @@ -0,0 +1,8 @@ +#!/bin/bash +set -e + +source hack/common.sh + +shfmt -i 4 -w ${KUBEVIRT_DIR}/cluster/ ${KUBEVIRT_DIR}/hack/ ${KUBEVIRT_DIR}/images/ +goimports -w -local kubevirt.io ${KUBEVIRT_DIR}/cmd/ ${KUBEVIRT_DIR}/pkg/ ${KUBEVIRT_DIR}/tests/ +(cd ${KUBEVIRT_DIR} && go vet ./cmd/... ./pkg/... ./tests/...) diff --git a/hack/docker-builder/entrypoint.sh b/hack/docker-builder/entrypoint.sh index 247ba188cdb4..00e6ce2692b3 100755 --- a/hack/docker-builder/entrypoint.sh +++ b/hack/docker-builder/entrypoint.sh @@ -1,5 +1,7 @@ #!/bin/bash +set -e +set -o pipefail source /etc/profile.d/gimme.sh export GOPATH="/root/go" -"$@" +eval "$@" diff --git a/hack/dockerized b/hack/dockerized index e3f2df45c7c8..d01bb44b8c9a 100755 --- a/hack/dockerized +++ b/hack/dockerized @@ -35,7 +35,7 @@ while ! rsync ${KUBEVIRT_DIR}/${RSYNCTEMP} "rsync://root@127.0.0.1:${RSYNCD_PORT done _rsync() { - rsync -avl "$@" + rsync -al "$@" } # Copy kubevirt into the persistent docker volume @@ -45,6 +45,6 @@ _rsync --delete --exclude '.glide*' --exclude "cluster/vagrant/.kubeconfig" --ex docker run --rm -v "${BUILDER}:/root:rw,z" -w "/root/go/src/kubevirt.io/kubevirt" -it ${BUILDER} "$@" # Copy the whole kubevirt data out to get generated sources and formatting changes -_rsync --exclude '.glide*' --exclude "vendor" --exclude "_out" --exclude ".vagrant" --exclude ".git" "rsync://root@127.0.0.1:${RSYNCD_PORT}/build" ${KUBEVIRT_DIR}/ +_rsync --exclude '.glide*' --exclude "_out" --exclude ".vagrant" --exclude ".git" "rsync://root@127.0.0.1:${RSYNCD_PORT}/build" ${KUBEVIRT_DIR}/ # Copy the build output out of the container, make sure that _out exactly matches the build result _rsync --delete "rsync://root@127.0.0.1:${RSYNCD_PORT}/out" ${OUT_DIR} diff --git a/hack/generate.sh b/hack/generate.sh new file mode 100755 index 000000000000..0516c708df17 --- /dev/null +++ b/hack/generate.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set -e + +source $(dirname "$0")/common.sh + +find ${KUBEVIRT_DIR}/pkg/ -name "*generated*.go" -exec rm {} -f \; + +${KUBEVIRT_DIR}/hack/build-go.sh generate ${WHAT} +/${KUBEVIRT_DIR}/hack/bootstrap-ginkgo.sh +(cd ${KUBEVIRT_DIR}/tools/openapispec/ && go build) +goimports -w -local kubevirt.io ${KUBEVIRT_DIR}/cmd/ ${KUBEVIRT_DIR}/pkg/ ${KUBEVIRT_DIR}/tests/ +${KUBEVIRT_DIR}/tools/openapispec/openapispec --dump-api-spec-path ${KUBEVIRT_DIR}/api/openapi-spec/swagger.json diff --git a/hack/glide-checksync.sh b/hack/glide-checksync.sh new file mode 100755 index 000000000000..dfd5722b66ab --- /dev/null +++ b/hack/glide-checksync.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -e + +source $(dirname "$0")/common.sh + +cd ${KUBEVIRT_DIR} + +test -f .glide.yaml.hash || md5sum glide.yaml >.glide.yaml.hash +if [ "$(md5sum glide.yaml)" != "$(cat .glide.yaml.hash)" ]; then + glide cc + glide update --strip-vendor + md5sum glide.yaml >.glide.yaml.hash + md5sum glide.lock >.glide.lock.hash +elif [ "$(md5sum glide.lock)" != "$(cat .glide.lock.hash)" ]; then + glide install --strip-vendor && md5sum glide.lock >.glide.lock.hash +fi