diff --git a/.gitignore b/.gitignore index f1c181e..5221915 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,8 @@ # Output of the go coverage tool, specifically when used with LiteIDE *.out + +/vendor +/.idea +/bin +/tmp \ No newline at end of file diff --git a/Dockerfile.builder b/Dockerfile.builder new file mode 100644 index 0000000..05c72a3 --- /dev/null +++ b/Dockerfile.builder @@ -0,0 +1,37 @@ +FROM centos:7 +LABEL maintainer "Devtools " +LABEL author "Devtools " +ENV LANG=en_US.utf8 +ARG USE_GO_VERSION_FROM_WEBSITE=0 + +# Some packages might seem weird but they are required by the RVM installer. +RUN yum install epel-release -y \ + && yum --enablerepo=centosplus --enablerepo=epel install -y \ + findutils \ + git \ + $(test "$USE_GO_VERSION_FROM_WEBSITE" != 1 && echo "golang") \ + make \ + procps-ng \ + tar \ + wget \ + which \ + && yum clean all + +RUN if [[ "$USE_GO_VERSION_FROM_WEBSITE" = 1 ]]; then cd /tmp \ + && wget https://dl.google.com/go/go1.10.linux-amd64.tar.gz \ + && echo "b5a64335f1490277b585832d1f6c7f8c6c11206cba5cd3f771dcb87b98ad1a33 go1.10.linux-amd64.tar.gz" > checksum \ + && sha256sum -c checksum \ + && tar -C /usr/local -xzf go1.10.linux-amd64.tar.gz \ + && rm -f go1.10.linux-amd64.tar.gz; \ + fi +ENV PATH=$PATH:/usr/local/go/bin + +# Get dep for Go package management and make sure the directory has full rwz permissions for non-root users +ENV GOPATH /tmp/go +RUN mkdir -p $GOPATH/bin && chmod a+rwx $GOPATH +RUN cd $GOPATH/bin \ + curl -L -s https://github.com/golang/dep/releases/download/v0.5.0/dep-linux-amd64 -o dep \ + echo "287b08291e14f1fae8ba44374b26a2b12eb941af3497ed0ca649253e21ba2f83 dep" > dep-linux-amd64.sha256 \ + sha256sum -c dep-linux-amd64.sha256 + +ENTRYPOINT ["/bin/bash"] diff --git a/Dockerfile.deploy b/Dockerfile.deploy new file mode 100644 index 0000000..cc648cd --- /dev/null +++ b/Dockerfile.deploy @@ -0,0 +1,18 @@ +FROM centos:7 +LABEL maintainer "Devtools " +LABEL author "Devtools " +ENV LANG=en_US.utf8 +ENV INSTALL_PREFIX=/usr/local/git-service + +# Create a non-root user and a group with the same name: "devconsole-operator" +ENV USER_NAME=devconsole-operator +RUN useradd --no-create-home -s /bin/bash ${USER_NAME} + +COPY bin/git-service ${INSTALL_PREFIX}/bin/git-service + +# From here onwards, any RUN, CMD, or ENTRYPOINT will be run under the following user +USER ${USER_NAME} + +WORKDIR ${INSTALL_PREFIX} + +ENTRYPOINT [ "bin/git-service" ] diff --git a/Dockerfile.deploy.rhel b/Dockerfile.deploy.rhel new file mode 100644 index 0000000..658ce73 --- /dev/null +++ b/Dockerfile.deploy.rhel @@ -0,0 +1,19 @@ +FROM quay.io/openshiftio/rhel-base-golang:latest + +LABEL maintainer "Devtools " +LABEL author "Devtools " +ENV LANG=en_US.utf8 +ENV INSTALL_PREFIX=/usr/local/git-service + +# Create a non-root user and a group with the same name: "devconsole-operator" +ENV USER_NAME=devconsole-operator +RUN useradd --no-create-home -s /bin/bash ${USER_NAME} + +COPY bin/git-service ${INSTALL_PREFIX}/bin/git-service + +# From here onwards, any RUN, CMD, or ENTRYPOINT will be run under the following user +USER ${USER_NAME} + +WORKDIR ${INSTALL_PREFIX} + +ENTRYPOINT [ "bin/git-service" ] diff --git a/Dockerfile.dev b/Dockerfile.dev new file mode 100644 index 0000000..3d0511c --- /dev/null +++ b/Dockerfile.dev @@ -0,0 +1,6 @@ +FROM centos:7 + +RUN mkdir -p /tmp/ +ADD bin/git-service / + +ENTRYPOINT ["/git-service"] diff --git a/Gopkg.lock b/Gopkg.lock new file mode 100644 index 0000000..6e624d3 --- /dev/null +++ b/Gopkg.lock @@ -0,0 +1,1175 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + branch = "master" + digest = "1:e53333a67873a0f14bdd0f9a1c0d453de594a5ac5981573209a8882abee34d89" + name = "github.com/MatousJobanek/build-environment-detector" + packages = [ + "detector", + "detector/environment", + "detector/git", + "detector/git/generic", + "detector/git/github", + "detector/git/gitlab", + ] + pruneopts = "UT" + revision = "39a544aec1dfe9aca2f0d7e0398104e2ddb2f92c" + +[[projects]] + digest = "1:002edd3097e9eb1ad56da7e29ed3bfdc8f85765d667a84246b38a7226c829ad2" + name = "github.com/NYTimes/gziphandler" + packages = ["."] + pruneopts = "UT" + revision = "56545f4a5d46df9a6648819d1664c3a03a13ffdb" + +[[projects]] + digest = "1:a2682518d905d662d984ef9959984ef87cecb777d379bfa9d9fe40e78069b3e4" + name = "github.com/PuerkitoBio/purell" + packages = ["."] + pruneopts = "UT" + revision = "44968752391892e1b0d0b821ee79e9a85fa13049" + version = "v1.1.1" + +[[projects]] + branch = "master" + digest = "1:c739832d67eb1e9cc478a19cc1a1ccd78df0397bf8a32978b759152e205f644b" + name = "github.com/PuerkitoBio/urlesc" + packages = ["."] + pruneopts = "UT" + revision = "de5bf2ad457846296e2031421a34e2568e304e35" + +[[projects]] + digest = "1:e4c72127d910a96daf869a44f3dd563b86dbe6931a172863a0e99c5ff04b59e4" + name = "github.com/Sirupsen/logrus" + packages = ["."] + pruneopts = "UT" + revision = "dae0fa8d5b0c810a8ab733fbd5510c7cae84eca4" + version = "v1.4.0" + +[[projects]] + branch = "master" + digest = "1:d6afaeed1502aa28e80a4ed0981d570ad91b2579193404256ce672ed0a609e0d" + name = "github.com/beorn7/perks" + packages = ["quantile"] + pruneopts = "UT" + revision = "3a771d992973f24aa725d07868b467d1ddfceafb" + +[[projects]] + digest = "1:b7e8c5fa66ebd2e6083cd4a6cc515f6d3c651fd04ad18a8276444bbcb172c583" + name = "github.com/coreos/etcd" + packages = [ + "auth/authpb", + "clientv3", + "etcdserver/api/v3rpc/rpctypes", + "etcdserver/etcdserverpb", + "mvcc/mvccpb", + "pkg/tlsutil", + "pkg/transport", + "pkg/types", + ] + pruneopts = "UT" + revision = "27fc7e2296f506182f58ce846e48f36b34fe6842" + version = "v3.3.10" + +[[projects]] + digest = "1:1da3a221f0bc090792d3a2a080ff09008427c0e0f0533a4ed6abd8994421da73" + name = "github.com/coreos/go-systemd" + packages = ["daemon"] + pruneopts = "UT" + revision = "39ca1b05acc7ad1220e09f133283b8859a8b71ab" + version = "v17" + +[[projects]] + digest = "1:6b21090f60571b20b3ddc2c8e48547dffcf409498ed6002c2cada023725ed377" + name = "github.com/davecgh/go-spew" + packages = ["spew"] + pruneopts = "UT" + revision = "782f4967f2dc4564575ca782fe2d04090b5faca8" + +[[projects]] + digest = "1:87c056b4f0548034ade51456237b47f723b901f373d7c11295f80da5d3b91950" + name = "github.com/emicklei/go-restful" + packages = [ + ".", + "log", + ] + pruneopts = "UT" + revision = "ff4f55a206334ef123e4f79bbf348980da81ca46" + +[[projects]] + digest = "1:b498b36dbb2b306d1c5205ee5236c9e60352be8f9eea9bf08186723a9f75b4f3" + name = "github.com/emirpasic/gods" + packages = [ + "containers", + "lists", + "lists/arraylist", + "trees", + "trees/binaryheap", + "utils", + ] + pruneopts = "UT" + revision = "1615341f118ae12f353cc8a983f35b584342c9b3" + version = "v1.12.0" + +[[projects]] + branch = "master" + digest = "1:36a5ff9459163d104f2af9776c8db63f3eb4339f527a00a9835c8d562eb116ba" + name = "github.com/evanphx/json-patch" + packages = ["."] + pruneopts = "UT" + revision = "5858425f75500d40c52783dce87d085a483ce135" + +[[projects]] + digest = "1:953a2628e4c5c72856b53f5470ed5e071c55eccf943d798d42908102af2a610f" + name = "github.com/go-openapi/jsonpointer" + packages = ["."] + pruneopts = "UT" + revision = "ef5f0afec364d3b9396b7b77b43dbe26bf1f8004" + version = "v0.18.0" + +[[projects]] + digest = "1:81210e0af657a0fb3638932ec68e645236bceefa4c839823db0c4d918f080895" + name = "github.com/go-openapi/jsonreference" + packages = ["."] + pruneopts = "UT" + revision = "8483a886a90412cd6858df4ea3483dce9c8e35a3" + version = "v0.18.0" + +[[projects]] + digest = "1:394fed5c0425fe01da3a34078adaa1682e4deaea6e5d232dde25c4034004c151" + name = "github.com/go-openapi/spec" + packages = ["."] + pruneopts = "UT" + revision = "5bae59e25b21498baea7f9d46e9c147ec106a42e" + version = "v0.17.2" + +[[projects]] + digest = "1:0005186c6608dd542239ac8e4f4f1e2e7c24d493e999113c46b93332f0362fc0" + name = "github.com/go-openapi/swag" + packages = ["."] + pruneopts = "UT" + revision = "1d29f06aebd59ccdf11ae04aa0334ded96e2d909" + version = "v0.18.0" + +[[projects]] + digest = "1:9886f20fc7188af1fb9059c6b6b29da154f87a05986a84ab297a5b6a779f230f" + name = "github.com/gogo/protobuf" + packages = [ + "gogoproto", + "proto", + "protoc-gen-gogo/descriptor", + "sortkeys", + ] + pruneopts = "UT" + revision = "342cbe0a04158f6dcb03ca0079991a51a4248c02" + version = "v0.5" + +[[projects]] + branch = "master" + digest = "1:b7cb6054d3dff43b38ad2e92492f220f57ae6087ee797dca298139776749ace8" + name = "github.com/golang/groupcache" + packages = ["lru"] + pruneopts = "UT" + revision = "5b532d6fd5efaf7fa130d4e859a2fde0fc3a9e1b" + +[[projects]] + digest = "1:239c4c7fd2159585454003d9be7207167970194216193a8a210b8d29576f19c9" + name = "github.com/golang/protobuf" + packages = [ + "proto", + "ptypes", + "ptypes/any", + "ptypes/duration", + "ptypes/timestamp", + ] + pruneopts = "UT" + revision = "c823c79ea1570fb5ff454033735a8e68575d1d0f" + version = "v1.3.0" + +[[projects]] + digest = "1:b4303d38d92c00af6603f3b865a9bd20e3c50cebe55489e5aeb721c26750e375" + name = "github.com/google/go-github" + packages = ["github"] + pruneopts = "UT" + revision = "7462feb2032c2da9e3b85e9b04e6853a6e9e14ca" + version = "v24.0.1" + +[[projects]] + digest = "1:a63cff6b5d8b95638bfe300385d93b2a6d9d687734b863da8e09dc834510a690" + name = "github.com/google/go-querystring" + packages = ["query"] + pruneopts = "UT" + revision = "44c6ddd0a2342c386950e880b658017258da92fc" + version = "v1.0.0" + +[[projects]] + branch = "master" + digest = "1:3ee90c0d94da31b442dde97c99635aaafec68d0b8a3c12ee2075c6bdabeec6bb" + name = "github.com/google/gofuzz" + packages = ["."] + pruneopts = "UT" + revision = "24818f796faf91cd76ec7bddd72458fbced7a6c1" + +[[projects]] + digest = "1:75eb87381d25cc75212f52358df9c3a2719584eaa9685cd510ce28699122f39d" + name = "github.com/googleapis/gnostic" + packages = [ + "OpenAPIv2", + "compiler", + "extensions", + ] + pruneopts = "UT" + revision = "0c5108395e2debce0d731cf0287ddf7242066aba" + +[[projects]] + digest = "1:bff41b67e290a59f174fb0f8689d7aba87294cded76fa0967718e1ce6d362426" + name = "github.com/grpc-ecosystem/go-grpc-prometheus" + packages = ["."] + pruneopts = "UT" + revision = "2500245aa6110c562d17020fb31a2c133d737799" + +[[projects]] + digest = "1:8ec8d88c248041a6df5f6574b87bc00e7e0b493881dad2e7ef47b11dc69093b5" + name = "github.com/hashicorp/golang-lru" + packages = [ + ".", + "simplelru", + ] + pruneopts = "UT" + revision = "20f1fb78b0740ba8c3cb143a61e86ba5c8669768" + version = "v0.5.0" + +[[projects]] + digest = "1:3e260afa138eab6492b531a3b3d10ab4cb70512d423faa78b8949dec76e66a21" + name = "github.com/imdario/mergo" + packages = ["."] + pruneopts = "UT" + revision = "9316a62528ac99aaecb4e47eadd6dc8aa6533d58" + version = "v0.3.5" + +[[projects]] + digest = "1:870d441fe217b8e689d7949fef6e43efbc787e50f200cb1e70dbca9204a1d6be" + name = "github.com/inconshreveable/mousetrap" + packages = ["."] + pruneopts = "UT" + revision = "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75" + version = "v1.0" + +[[projects]] + branch = "master" + digest = "1:62fe3a7ea2050ecbd753a71889026f83d73329337ada66325cbafd5dea5f713d" + name = "github.com/jbenet/go-context" + packages = ["io"] + pruneopts = "UT" + revision = "d14ea06fba99483203c19d92cfcd13ebe73135f4" + +[[projects]] + digest = "1:eaefc85d32c03e5f0c2b88ea2f79fce3d993e2c78316d21319575dd4ea9153ca" + name = "github.com/json-iterator/go" + packages = ["."] + pruneopts = "UT" + revision = "ab8a2e0c74be9d3be70b3184d9acc634935ded82" + version = "1.1.4" + +[[projects]] + digest = "1:ae5f4d0779a45e2cb3075d8b3ece6c623e171407f4aac83521392ff06d188871" + name = "github.com/kevinburke/ssh_config" + packages = ["."] + pruneopts = "UT" + revision = "81db2a75821ed34e682567d48be488a1c3121088" + version = "0.5" + +[[projects]] + digest = "1:31e761d97c76151dde79e9d28964a812c46efc5baee4085b86f68f0c654450de" + name = "github.com/konsorten/go-windows-terminal-sequences" + packages = ["."] + pruneopts = "UT" + revision = "f55edac94c9bbba5d6182a4be46d86a2c9b5b50e" + version = "v1.0.2" + +[[projects]] + branch = "master" + digest = "1:84a5a2b67486d5d67060ac393aa255d05d24ed5ee41daecd5635ec22657b6492" + name = "github.com/mailru/easyjson" + packages = [ + "buffer", + "jlexer", + "jwriter", + ] + pruneopts = "UT" + revision = "6243d8e04c3f819e79757e8bc3faa15c3cb27003" + +[[projects]] + digest = "1:ff5ebae34cfbf047d505ee150de27e60570e8c394b3b8fdbb720ff6ac71985fc" + name = "github.com/matttproud/golang_protobuf_extensions" + packages = ["pbutil"] + pruneopts = "UT" + revision = "c12348ce28de40eed0136aa2b644d0ee0650e56c" + version = "v1.0.1" + +[[projects]] + digest = "1:5d231480e1c64a726869bc4142d270184c419749d34f167646baa21008eb0a79" + name = "github.com/mitchellh/go-homedir" + packages = ["."] + pruneopts = "UT" + revision = "af06845cf3004701891bf4fdb884bfe4920b3727" + version = "v1.1.0" + +[[projects]] + digest = "1:33422d238f147d247752996a26574ac48dcf472976eda7f5134015f06bf16563" + name = "github.com/modern-go/concurrent" + packages = ["."] + pruneopts = "UT" + revision = "bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94" + version = "1.0.3" + +[[projects]] + digest = "1:c56ad36f5722eb07926c979d5e80676ee007a9e39e7808577b9d87ec92b00460" + name = "github.com/modern-go/reflect2" + packages = ["."] + pruneopts = "UT" + revision = "94122c33edd36123c84d5368cfb2b69df93a0ec8" + version = "v1.0.1" + +[[projects]] + digest = "1:b8a91524c7e262bcf2fde6e6bdcebfcaa6450ad073af6df6301fd5f6c32a838b" + name = "github.com/moovweb/rubex" + packages = ["."] + pruneopts = "UT" + revision = "cb849acea6148000db8a55743f71476b0897ea41" + version = "6.3.107" + +[[projects]] + branch = "master" + digest = "1:24df057f15e7a09e75c1241cbe6f6590fd3eac9804f1110b02efade3214f042d" + name = "github.com/munnerz/goautoneg" + packages = ["."] + pruneopts = "UT" + revision = "a547fc61f48d567d5b4ec6f8aee5573d8efce11d" + +[[projects]] + digest = "1:9072181164e616e422cbfbe48ca9ac249a4d76301ca0876c9f56b937cf214a2f" + name = "github.com/pborman/uuid" + packages = ["."] + pruneopts = "UT" + revision = "ca53cad383cad2479bbba7f7a1a05797ec1386e4" + +[[projects]] + digest = "1:b2ee62e09bec113cf086d2ce0769efcc7bf79481aba8373fd8f7884e94df3462" + name = "github.com/pelletier/go-buffruneio" + packages = ["."] + pruneopts = "UT" + revision = "c37440a7cf42ac63b919c752ca73a85067e05992" + version = "v0.2.0" + +[[projects]] + digest = "1:75d51eeab0df85a3cea9e1297ccd3183b20a10cb4b48c753d8ec8d113cc14250" + name = "github.com/prometheus/client_golang" + packages = [ + "prometheus", + "prometheus/internal", + ] + pruneopts = "UT" + revision = "505eaef017263e299324067d40ca2c48f6a2cf50" + version = "v0.9.2" + +[[projects]] + branch = "master" + digest = "1:2d5cd61daa5565187e1d96bae64dbbc6080dacf741448e9629c64fd93203b0d4" + name = "github.com/prometheus/client_model" + packages = ["go"] + pruneopts = "UT" + revision = "fd36f4220a901265f90734c3183c5f0c91daa0b8" + +[[projects]] + digest = "1:35cf6bdf68db765988baa9c4f10cc5d7dda1126a54bd62e252dbcd0b1fc8da90" + name = "github.com/prometheus/common" + packages = [ + "expfmt", + "internal/bitbucket.org/ww/goautoneg", + "model", + ] + pruneopts = "UT" + revision = "cfeb6f9992ffa54aaa4f2170ade4067ee478b250" + version = "v0.2.0" + +[[projects]] + branch = "master" + digest = "1:01cd0cd47758f04c5604daa3be4637e2afa1e0c15af7e08289e95360369e4f48" + name = "github.com/prometheus/procfs" + packages = [ + ".", + "internal/util", + "iostats", + "nfs", + "xfs", + ] + pruneopts = "UT" + revision = "d0f344d83b0c80a1bc03b547a2374a9ec6711144" + +[[projects]] + digest = "1:d917313f309bda80d27274d53985bc65651f81a5b66b820749ac7f8ef061fd04" + name = "github.com/sergi/go-diff" + packages = ["diffmatchpatch"] + pruneopts = "UT" + revision = "1744e2970ca51c86172c8190fadad617561ed6e7" + version = "v1.0.0" + +[[projects]] + digest = "1:645cabccbb4fa8aab25a956cbcbdf6a6845ca736b2c64e197ca7cbb9d210b939" + name = "github.com/spf13/cobra" + packages = ["."] + pruneopts = "UT" + revision = "ef82de70bb3f60c65fb8eebacbb2d122ef517385" + version = "v0.0.3" + +[[projects]] + digest = "1:9424f440bba8f7508b69414634aef3b2b3a877e522d8a4624692412805407bb7" + name = "github.com/spf13/pflag" + packages = ["."] + pruneopts = "UT" + revision = "583c0c0531f06d5278b7d917446061adc344b5cd" + version = "v1.0.1" + +[[projects]] + digest = "1:e4ed0afd67bf7be353921665cdac50834c867ff1bba153efc0745b755a7f5905" + name = "github.com/src-d/gcfg" + packages = [ + ".", + "scanner", + "token", + "types", + ] + pruneopts = "UT" + revision = "1ac3a1ac202429a54835fe8408a92880156b489d" + version = "v1.4.0" + +[[projects]] + digest = "1:5a732e85cb3ccd95056ac8885ccb4ce646354c9030df90c0f0b23cae23b4121a" + name = "github.com/toqueteos/trie" + packages = ["."] + pruneopts = "UT" + revision = "683ae57f27ac5c2afec902631ed8b9cda1d0f481" + version = "v1.0.0" + +[[projects]] + digest = "1:9a89389cfcb4290761df037aeac1e6daf680ffdc87486baa19f99f17c0056b9b" + name = "github.com/xanzy/go-gitlab" + packages = ["."] + pruneopts = "UT" + revision = "8e525d783950ddfc35d109e48af26f4cb70dde4a" + version = "v0.15.0" + +[[projects]] + digest = "1:172f94a6b3644a8f9e6b5e5b7fc9fe1e42d424f52a0300b2e7ab1e57db73f85d" + name = "github.com/xanzy/ssh-agent" + packages = ["."] + pruneopts = "UT" + revision = "6a3e2ff9e7c564f36873c2e36413f634534f1c44" + version = "v0.2.1" + +[[projects]] + digest = "1:dfcb1b2db354cafa48fc3cdafe4905a08bec4a9757919ab07155db0ca23855b4" + name = "golang.org/x/crypto" + packages = [ + "cast5", + "curve25519", + "ed25519", + "ed25519/internal/edwards25519", + "internal/chacha20", + "internal/subtle", + "openpgp", + "openpgp/armor", + "openpgp/elgamal", + "openpgp/errors", + "openpgp/packet", + "openpgp/s2k", + "poly1305", + "ssh", + "ssh/agent", + "ssh/knownhosts", + "ssh/terminal", + ] + pruneopts = "UT" + revision = "de0752318171da717af4ce24d0a2e8626afaeb11" + +[[projects]] + branch = "release-branch.go1.10" + digest = "1:5dd41bb0a1256029864c398735df720345044232e06ed4ac23e1bf96242f9c1d" + name = "golang.org/x/net" + packages = [ + "context", + "http2", + "http2/hpack", + "idna", + "internal/timeseries", + "lex/httplex", + "trace", + "websocket", + ] + pruneopts = "UT" + revision = "0ed95abb35c445290478a5348a7b38bb154135fd" + +[[projects]] + digest = "1:9359217acc6040b4be710ce34473acef28023ad39bfafecea34ffaea7f1e1890" + name = "golang.org/x/oauth2" + packages = [ + ".", + "internal", + ] + pruneopts = "UT" + revision = "a6bd8cefa1811bd24b86f8902872e4e8225f74c4" + +[[projects]] + branch = "master" + digest = "1:1be6480d6816d23e125645a42e38c9a2637a460d8470f432be6ffc02306c5488" + name = "golang.org/x/sys" + packages = [ + "unix", + "windows", + ] + pruneopts = "UT" + revision = "b294cbcfc56d2a65a30c02c78722b5df061e99b8" + +[[projects]] + digest = "1:0c56024909189aee3364b7f21a95a27459f718aa7c199a5c111c36cfffd9eaef" + name = "golang.org/x/text" + packages = [ + "collate", + "collate/build", + "internal/colltab", + "internal/gen", + "internal/tag", + "internal/triegen", + "internal/ucd", + "language", + "secure/bidirule", + "transform", + "unicode/bidi", + "unicode/cldr", + "unicode/norm", + "unicode/rangetable", + "width", + ] + pruneopts = "UT" + revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0" + version = "v0.3.0" + +[[projects]] + digest = "1:d37b0ef2944431fe9e8ef35c6fffc8990d9e2ca300588df94a6890f3649ae365" + name = "golang.org/x/time" + packages = ["rate"] + pruneopts = "UT" + revision = "f51c12702a4d776e4c1fa9b0fabab841babae631" + +[[projects]] + digest = "1:6f3bd49ddf2e104e52062774d797714371fac1b8bddfd8e124ce78e6b2264a10" + name = "google.golang.org/appengine" + packages = [ + "internal", + "internal/base", + "internal/datastore", + "internal/log", + "internal/remote_api", + "internal/urlfetch", + "urlfetch", + ] + pruneopts = "UT" + revision = "e9657d882bb81064595ca3b56cbe2546bbabf7b1" + version = "v1.4.0" + +[[projects]] + branch = "master" + digest = "1:077c1c599507b3b3e9156d17d36e1e61928ee9b53a5b420f10f28ebd4a0b275c" + name = "google.golang.org/genproto" + packages = ["googleapis/rpc/status"] + pruneopts = "UT" + revision = "6e86cb5d2f12401bdd82a5eccbd701b5a697e63e" + +[[projects]] + digest = "1:45101b53b1b93d50e2464e3b164bfa72cc77229fb998cfcd029987006488c641" + name = "google.golang.org/grpc" + packages = [ + ".", + "balancer", + "codes", + "connectivity", + "credentials", + "grpclb/grpc_lb_v1/messages", + "grpclog", + "health/grpc_health_v1", + "internal", + "keepalive", + "metadata", + "naming", + "peer", + "resolver", + "stats", + "status", + "tap", + "transport", + ] + pruneopts = "UT" + revision = "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" + version = "v1.7.5" + +[[projects]] + digest = "1:ef72505cf098abdd34efeea032103377bec06abb61d8a06f002d5d296a4b1185" + name = "gopkg.in/inf.v0" + packages = ["."] + pruneopts = "UT" + revision = "3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4" + version = "v0.9.0" + +[[projects]] + digest = "1:c805e517269b0ba4c21ded5836019ed7d16953d4026cb7d00041d039c7906be9" + name = "gopkg.in/natefinch/lumberjack.v2" + packages = ["."] + pruneopts = "UT" + revision = "a96e63847dc3c67d17befa69c303767e2f84e54f" + version = "v2.1" + +[[projects]] + digest = "1:3e84e4f84d331c8c74f5fce34e647e78ea736496fc27d1983fdcd487f7246b8b" + name = "gopkg.in/src-d/enry.v1" + packages = [ + ".", + "data", + "data/rule", + "internal/tokenizer", + "regex", + ] + pruneopts = "UT" + revision = "e067e4504402176864d8b5464bfed5b7e6d40307" + version = "v1.7.1" + +[[projects]] + digest = "1:6252ee69502cea19153314d10afa5ac3a9ffa65e726ea531deb2e1c27ed50fe6" + name = "gopkg.in/src-d/go-billy.v4" + packages = [ + ".", + "helper/chroot", + "helper/polyfill", + "memfs", + "osfs", + "util", + ] + pruneopts = "UT" + revision = "982626487c60a5252e7d0b695ca23fb0fa2fd670" + version = "v4.3.0" + +[[projects]] + digest = "1:44801e4be7066a82dc7a7f608d31f99c5c0f5a65a0215b37401a5657ce52940d" + name = "gopkg.in/src-d/go-git.v4" + packages = [ + ".", + "config", + "internal/revision", + "internal/url", + "plumbing", + "plumbing/cache", + "plumbing/filemode", + "plumbing/format/config", + "plumbing/format/diff", + "plumbing/format/gitignore", + "plumbing/format/idxfile", + "plumbing/format/index", + "plumbing/format/objfile", + "plumbing/format/packfile", + "plumbing/format/pktline", + "plumbing/object", + "plumbing/protocol/packp", + "plumbing/protocol/packp/capability", + "plumbing/protocol/packp/sideband", + "plumbing/revlist", + "plumbing/storer", + "plumbing/transport", + "plumbing/transport/client", + "plumbing/transport/file", + "plumbing/transport/git", + "plumbing/transport/http", + "plumbing/transport/internal/common", + "plumbing/transport/server", + "plumbing/transport/ssh", + "storage", + "storage/filesystem", + "storage/filesystem/dotgit", + "storage/memory", + "utils/binary", + "utils/diff", + "utils/ioutil", + "utils/merkletrie", + "utils/merkletrie/filesystem", + "utils/merkletrie/index", + "utils/merkletrie/internal/frame", + "utils/merkletrie/noder", + ] + pruneopts = "UT" + revision = "db6c41c156481962abf9a55a324858674c25ab08" + version = "v4.10.0" + +[[projects]] + digest = "1:98e121dbd49eb03c58bd8ef3b76322b2fdc3676cf11fa0084bb17ff01b2aa704" + name = "gopkg.in/toqueteos/substring.v1" + packages = ["."] + pruneopts = "UT" + revision = "c5f61671513240ddf5563635cc4a90e9f3ae4710" + version = "v1.0.2" + +[[projects]] + digest = "1:78d374b493e747afa9fbb2119687e3740a7fb8d0ebabddfef0a012593aaecbb3" + name = "gopkg.in/warnings.v0" + packages = ["."] + pruneopts = "UT" + revision = "ec4a0fea49c7b46c2aeb0b51aac55779c607e52b" + version = "v0.1.2" + +[[projects]] + digest = "1:342378ac4dcb378a5448dd723f0784ae519383532f5e70ade24132c4c8693202" + name = "gopkg.in/yaml.v2" + packages = ["."] + pruneopts = "UT" + revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183" + version = "v2.2.1" + +[[projects]] + branch = "master" + digest = "1:9ff5263d7d241dc9a651111a830cdab126f45a0099b1a4319fcbe13a84dee7b1" + name = "k8s.io/api" + packages = [ + "admission/v1beta1", + "admissionregistration/v1beta1", + "apps/v1", + "apps/v1beta1", + "apps/v1beta2", + "auditregistration/v1alpha1", + "authentication/v1", + "authentication/v1beta1", + "authorization/v1", + "authorization/v1beta1", + "autoscaling/v1", + "autoscaling/v2beta1", + "autoscaling/v2beta2", + "batch/v1", + "batch/v1beta1", + "batch/v2alpha1", + "certificates/v1beta1", + "coordination/v1", + "coordination/v1beta1", + "core/v1", + "events/v1beta1", + "extensions/v1beta1", + "networking/v1", + "networking/v1beta1", + "policy/v1beta1", + "rbac/v1", + "rbac/v1alpha1", + "rbac/v1beta1", + "scheduling/v1", + "scheduling/v1alpha1", + "scheduling/v1beta1", + "settings/v1alpha1", + "storage/v1", + "storage/v1alpha1", + "storage/v1beta1", + ] + pruneopts = "UT" + revision = "16f65c82b8fa063598f779f64079bd40275a0248" + +[[projects]] + branch = "master" + digest = "1:a32e779a9aa1193c0c6f0298e74e640a2d556ed07a58d0530245aafddeec1c4c" + name = "k8s.io/apimachinery" + packages = [ + "pkg/api/equality", + "pkg/api/errors", + "pkg/api/meta", + "pkg/api/resource", + "pkg/api/validation", + "pkg/api/validation/path", + "pkg/apis/meta/internalversion", + "pkg/apis/meta/v1", + "pkg/apis/meta/v1/unstructured", + "pkg/apis/meta/v1/validation", + "pkg/apis/meta/v1beta1", + "pkg/conversion", + "pkg/conversion/queryparams", + "pkg/fields", + "pkg/labels", + "pkg/runtime", + "pkg/runtime/schema", + "pkg/runtime/serializer", + "pkg/runtime/serializer/json", + "pkg/runtime/serializer/protobuf", + "pkg/runtime/serializer/recognizer", + "pkg/runtime/serializer/streaming", + "pkg/runtime/serializer/versioning", + "pkg/selection", + "pkg/types", + "pkg/util/cache", + "pkg/util/clock", + "pkg/util/diff", + "pkg/util/errors", + "pkg/util/framer", + "pkg/util/intstr", + "pkg/util/json", + "pkg/util/mergepatch", + "pkg/util/naming", + "pkg/util/net", + "pkg/util/rand", + "pkg/util/runtime", + "pkg/util/sets", + "pkg/util/strategicpatch", + "pkg/util/uuid", + "pkg/util/validation", + "pkg/util/validation/field", + "pkg/util/wait", + "pkg/util/waitgroup", + "pkg/util/yaml", + "pkg/version", + "pkg/watch", + "third_party/forked/golang/json", + "third_party/forked/golang/reflect", + ] + pruneopts = "UT" + revision = "2f7e9cae4418a86ea03618fea183bfe9fe43c574" + +[[projects]] + branch = "master" + digest = "1:eef922860edc164a13aacd8277d95bd30044925c1664cbf798f35a7ca1d577f3" + name = "k8s.io/apiserver" + packages = [ + "pkg/admission", + "pkg/admission/configuration", + "pkg/admission/initializer", + "pkg/admission/metrics", + "pkg/admission/plugin/namespace/lifecycle", + "pkg/admission/plugin/webhook/config", + "pkg/admission/plugin/webhook/config/apis/webhookadmission", + "pkg/admission/plugin/webhook/config/apis/webhookadmission/v1alpha1", + "pkg/admission/plugin/webhook/errors", + "pkg/admission/plugin/webhook/generic", + "pkg/admission/plugin/webhook/mutating", + "pkg/admission/plugin/webhook/namespace", + "pkg/admission/plugin/webhook/request", + "pkg/admission/plugin/webhook/rules", + "pkg/admission/plugin/webhook/util", + "pkg/admission/plugin/webhook/validating", + "pkg/apis/apiserver", + "pkg/apis/apiserver/install", + "pkg/apis/apiserver/v1alpha1", + "pkg/apis/audit", + "pkg/apis/audit/install", + "pkg/apis/audit/v1", + "pkg/apis/audit/v1alpha1", + "pkg/apis/audit/v1beta1", + "pkg/apis/audit/validation", + "pkg/audit", + "pkg/audit/event", + "pkg/audit/policy", + "pkg/audit/util", + "pkg/authentication/authenticator", + "pkg/authentication/authenticatorfactory", + "pkg/authentication/group", + "pkg/authentication/request/anonymous", + "pkg/authentication/request/bearertoken", + "pkg/authentication/request/headerrequest", + "pkg/authentication/request/union", + "pkg/authentication/request/websocket", + "pkg/authentication/request/x509", + "pkg/authentication/serviceaccount", + "pkg/authentication/token/cache", + "pkg/authentication/token/tokenfile", + "pkg/authentication/user", + "pkg/authorization/authorizer", + "pkg/authorization/authorizerfactory", + "pkg/authorization/path", + "pkg/authorization/union", + "pkg/endpoints", + "pkg/endpoints/discovery", + "pkg/endpoints/filters", + "pkg/endpoints/handlers", + "pkg/endpoints/handlers/fieldmanager", + "pkg/endpoints/handlers/fieldmanager/internal", + "pkg/endpoints/handlers/negotiation", + "pkg/endpoints/handlers/responsewriters", + "pkg/endpoints/metrics", + "pkg/endpoints/openapi", + "pkg/endpoints/request", + "pkg/features", + "pkg/registry/generic", + "pkg/registry/generic/registry", + "pkg/registry/rest", + "pkg/server", + "pkg/server/filters", + "pkg/server/healthz", + "pkg/server/httplog", + "pkg/server/mux", + "pkg/server/options", + "pkg/server/resourceconfig", + "pkg/server/routes", + "pkg/server/storage", + "pkg/storage", + "pkg/storage/cacher", + "pkg/storage/errors", + "pkg/storage/etcd", + "pkg/storage/etcd/metrics", + "pkg/storage/etcd3", + "pkg/storage/names", + "pkg/storage/storagebackend", + "pkg/storage/storagebackend/factory", + "pkg/storage/value", + "pkg/util/dryrun", + "pkg/util/feature", + "pkg/util/flushwriter", + "pkg/util/openapi", + "pkg/util/webhook", + "pkg/util/wsstream", + "plugin/pkg/audit/buffered", + "plugin/pkg/audit/dynamic", + "plugin/pkg/audit/dynamic/enforced", + "plugin/pkg/audit/log", + "plugin/pkg/audit/truncate", + "plugin/pkg/audit/webhook", + "plugin/pkg/authenticator/token/webhook", + "plugin/pkg/authorizer/webhook", + ] + pruneopts = "UT" + revision = "74ad4aa47e795ff8391658576ed6a681034d2304" + +[[projects]] + branch = "master" + digest = "1:4c4f43f9f45a44dd14905fc0b854e9e5820c7026b0950b14a3c4b6c2a282f347" + name = "k8s.io/client-go" + packages = [ + "discovery", + "informers", + "informers/admissionregistration", + "informers/admissionregistration/v1beta1", + "informers/apps", + "informers/apps/v1", + "informers/apps/v1beta1", + "informers/apps/v1beta2", + "informers/auditregistration", + "informers/auditregistration/v1alpha1", + "informers/autoscaling", + "informers/autoscaling/v1", + "informers/autoscaling/v2beta1", + "informers/autoscaling/v2beta2", + "informers/batch", + "informers/batch/v1", + "informers/batch/v1beta1", + "informers/batch/v2alpha1", + "informers/certificates", + "informers/certificates/v1beta1", + "informers/coordination", + "informers/coordination/v1", + "informers/coordination/v1beta1", + "informers/core", + "informers/core/v1", + "informers/events", + "informers/events/v1beta1", + "informers/extensions", + "informers/extensions/v1beta1", + "informers/internalinterfaces", + "informers/networking", + "informers/networking/v1", + "informers/networking/v1beta1", + "informers/policy", + "informers/policy/v1beta1", + "informers/rbac", + "informers/rbac/v1", + "informers/rbac/v1alpha1", + "informers/rbac/v1beta1", + "informers/scheduling", + "informers/scheduling/v1", + "informers/scheduling/v1alpha1", + "informers/scheduling/v1beta1", + "informers/settings", + "informers/settings/v1alpha1", + "informers/storage", + "informers/storage/v1", + "informers/storage/v1alpha1", + "informers/storage/v1beta1", + "kubernetes", + "kubernetes/scheme", + "kubernetes/typed/admissionregistration/v1beta1", + "kubernetes/typed/apps/v1", + "kubernetes/typed/apps/v1beta1", + "kubernetes/typed/apps/v1beta2", + "kubernetes/typed/auditregistration/v1alpha1", + "kubernetes/typed/authentication/v1", + "kubernetes/typed/authentication/v1beta1", + "kubernetes/typed/authorization/v1", + "kubernetes/typed/authorization/v1beta1", + "kubernetes/typed/autoscaling/v1", + "kubernetes/typed/autoscaling/v2beta1", + "kubernetes/typed/autoscaling/v2beta2", + "kubernetes/typed/batch/v1", + "kubernetes/typed/batch/v1beta1", + "kubernetes/typed/batch/v2alpha1", + "kubernetes/typed/certificates/v1beta1", + "kubernetes/typed/coordination/v1", + "kubernetes/typed/coordination/v1beta1", + "kubernetes/typed/core/v1", + "kubernetes/typed/events/v1beta1", + "kubernetes/typed/extensions/v1beta1", + "kubernetes/typed/networking/v1", + "kubernetes/typed/networking/v1beta1", + "kubernetes/typed/policy/v1beta1", + "kubernetes/typed/rbac/v1", + "kubernetes/typed/rbac/v1alpha1", + "kubernetes/typed/rbac/v1beta1", + "kubernetes/typed/scheduling/v1", + "kubernetes/typed/scheduling/v1alpha1", + "kubernetes/typed/scheduling/v1beta1", + "kubernetes/typed/settings/v1alpha1", + "kubernetes/typed/storage/v1", + "kubernetes/typed/storage/v1alpha1", + "kubernetes/typed/storage/v1beta1", + "listers/admissionregistration/v1beta1", + "listers/apps/v1", + "listers/apps/v1beta1", + "listers/apps/v1beta2", + "listers/auditregistration/v1alpha1", + "listers/autoscaling/v1", + "listers/autoscaling/v2beta1", + "listers/autoscaling/v2beta2", + "listers/batch/v1", + "listers/batch/v1beta1", + "listers/batch/v2alpha1", + "listers/certificates/v1beta1", + "listers/coordination/v1", + "listers/coordination/v1beta1", + "listers/core/v1", + "listers/events/v1beta1", + "listers/extensions/v1beta1", + "listers/networking/v1", + "listers/networking/v1beta1", + "listers/policy/v1beta1", + "listers/rbac/v1", + "listers/rbac/v1alpha1", + "listers/rbac/v1beta1", + "listers/scheduling/v1", + "listers/scheduling/v1alpha1", + "listers/scheduling/v1beta1", + "listers/settings/v1alpha1", + "listers/storage/v1", + "listers/storage/v1alpha1", + "listers/storage/v1beta1", + "pkg/apis/clientauthentication", + "pkg/apis/clientauthentication/v1alpha1", + "pkg/apis/clientauthentication/v1beta1", + "pkg/version", + "plugin/pkg/client/auth/exec", + "rest", + "rest/watch", + "tools/auth", + "tools/cache", + "tools/clientcmd", + "tools/clientcmd/api", + "tools/clientcmd/api/latest", + "tools/clientcmd/api/v1", + "tools/metrics", + "tools/pager", + "tools/record", + "tools/record/util", + "tools/reference", + "transport", + "util/cert", + "util/connrotation", + "util/flowcontrol", + "util/homedir", + "util/keyutil", + "util/retry", + ] + pruneopts = "UT" + revision = "9c9f7f424e65af6ded246bd4ba1a1cec988acc7b" + +[[projects]] + branch = "master" + digest = "1:62505062b5c666aa8a7713dbd199cae0469e08f2df6c61af56970f2a1a4a2a57" + name = "k8s.io/component-base" + packages = [ + "cli/flag", + "logs", + ] + pruneopts = "UT" + revision = "1925c57e3358154fd54383773de0c0c7710a9196" + +[[projects]] + digest = "1:e2999bf1bb6eddc2a6aa03fe5e6629120a53088926520ca3b4765f77d7ff7eab" + name = "k8s.io/klog" + packages = ["."] + pruneopts = "UT" + revision = "8139d8cb77af419532b33dfa7dd09fbc5f1d344f" + +[[projects]] + digest = "1:205a4e040577735acc45ea2be72ed60020c4ed1f771bc79971b598c99c67db35" + name = "k8s.io/kube-openapi" + packages = [ + "pkg/builder", + "pkg/common", + "pkg/handler", + "pkg/schemaconv", + "pkg/util", + "pkg/util/proto", + ] + pruneopts = "UT" + revision = "b3a7cee44a305be0a69e1b9ac03018307287e1b0" + +[[projects]] + branch = "master" + digest = "1:14e8a3b53e6d8cb5f44783056b71bb2ca1ac7e333939cc97f3e50b579c920845" + name = "k8s.io/utils" + packages = [ + "buffer", + "integer", + "trace", + ] + pruneopts = "UT" + revision = "c2654d5206da6b7b6ace12841e8f359bb89b443c" + +[[projects]] + digest = "1:060c1112d3b1639a0cfc6cceb2c90e61b902ddf1897c2ffbdbe2bf067661242c" + name = "sigs.k8s.io/structured-merge-diff" + packages = [ + "fieldpath", + "merge", + "schema", + "typed", + "value", + ] + pruneopts = "UT" + revision = "e5e029740eb81ee0217ecf9d950c25a0eeb9688a" + +[[projects]] + digest = "1:7719608fe0b52a4ece56c2dde37bedd95b938677d1ab0f84b8a7852e4c59f849" + name = "sigs.k8s.io/yaml" + packages = ["."] + pruneopts = "UT" + revision = "fd68e9863619f6ec2fdd8625fe1f02e7c877e480" + version = "v1.1.0" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + input-imports = [ + "github.com/MatousJobanek/build-environment-detector/detector", + "github.com/MatousJobanek/build-environment-detector/detector/git", + "github.com/emicklei/go-restful", + "github.com/spf13/cobra", + "k8s.io/apimachinery/pkg/apis/meta/v1", + "k8s.io/apimachinery/pkg/runtime", + "k8s.io/apimachinery/pkg/runtime/schema", + "k8s.io/apimachinery/pkg/runtime/serializer", + "k8s.io/apimachinery/pkg/util/errors", + "k8s.io/apimachinery/pkg/util/runtime", + "k8s.io/apimachinery/pkg/version", + "k8s.io/apiserver/pkg/server", + "k8s.io/apiserver/pkg/server/options", + "k8s.io/component-base/logs", + ] + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml new file mode 100644 index 0000000..3960a87 --- /dev/null +++ b/Gopkg.toml @@ -0,0 +1,42 @@ +# Gopkg.toml example +# +# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html +# for detailed Gopkg.toml documentation. +# +# required = ["github.com/user/thing/cmd/thing"] +# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] +# +# [[constraint]] +# name = "github.com/user/project" +# version = "1.0.0" +# +# [[constraint]] +# name = "github.com/user/project2" +# branch = "dev" +# source = "github.com/myfork/project2" +# +# [[override]] +# name = "github.com/x/y" +# version = "2.4.0" +# +# [prune] +# non-go = false +# go-tests = true +# unused-packages = true + + +[[constraint]] + branch = "master" + name = "k8s.io/apiserver" + +[[constraint]] + branch = "master" + name = "k8s.io/component-base" + +[prune] + go-tests = true + unused-packages = true + +[[constraint]] + branch = "master" + name = "github.com/MatousJobanek/build-environment-detector" diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..78758eb --- /dev/null +++ b/Makefile @@ -0,0 +1,272 @@ +PROJECT_NAME=git-service +PACKAGE_NAME:=github.com/redhat-developer/$(PROJECT_NAME) +CUR_DIR=$(shell pwd) +TMP_PATH=$(CUR_DIR)/tmp +INSTALL_PREFIX=$(CUR_DIR)/bin +VENDOR_DIR=vendor +INCLUDE_DIR=make +SOURCE_DIR ?= . +SOURCES := $(shell find $(SOURCE_DIR) -path $(SOURCE_DIR)/vendor -prune -o -name '*.go' -print) + +BINARY_SERVER_BIN=$(INSTALL_PREFIX)/git-service +GO_BIN_NAME=go +GIT_BIN_NAME=git +DEP_BIN_NAME=dep +DOCKER_BIN_NAME=docker +UNAME_S=$(shell uname -s) +GOCOV_BIN=$(VENDOR_DIR)/github.com/axw/gocov/gocov/gocov +GOCOVMERGE_BIN=$(VENDOR_DIR)/github.com/wadey/gocovmerge/gocovmerge +GOCYCLO_DIR=$(VENDOR_DIR)/github.com/fzipp/gocyclo +GOCYCLO_BIN=$(GOCYCLO_DIR)/gocyclo +GOLANGCI_LINT_BIN_NAME:=golangci-lint + +# declares variable that are OS-sensitive +include ./$(INCLUDE_DIR)/test.mk +include ./$(INCLUDE_DIR)/Makefile.dev + +DOCKER_BIN := $(shell command -v $(DOCKER_BIN_NAME) 2> /dev/null) +include ./$(INCLUDE_DIR)/docker.mk + +# This is a fix for a non-existing user in passwd file when running in a docker +# container and trying to clone repos of dependencies +GIT_COMMITTER_NAME ?= "user" +GIT_COMMITTER_EMAIL ?= "user@example.com" +export GIT_COMMITTER_NAME +export GIT_COMMITTER_EMAIL + +COMMIT=$(shell git rev-parse HEAD 2>/dev/null) +GITUNTRACKEDCHANGES := $(shell git status --porcelain --untracked-files=no) +ifneq ($(GITUNTRACKEDCHANGES),) + COMMIT := $(COMMIT)-dirty +endif +BUILD_TIME=`date -u '+%Y-%m-%dT%H:%M:%SZ'` + +.DEFAULT_GOAL := help + +# Call this function with $(call log-info,"Your message") +define log-info = + @echo "INFO: $(1)" +endef + +# ------------------------------------------------------------------- +# Docker build +# ------------------------------------------------------------------- +BUILD_DIR = bin +REGISTRY_URI = quay.io +REGISTRY_NS = ${PROJECT_NAME} +REGISTRY_IMAGE = ${PROJECT_NAME} + +ifeq ($(TARGET),rhel) + REGISTRY_URL := ${REGISTRY_URI}/openshiftio/rhel-${REGISTRY_NS}-${REGISTRY_IMAGE} + DOCKERFILE := Dockerfile.rhel +else + REGISTRY_URL := ${REGISTRY_URI}/openshiftio/${REGISTRY_NS}-${REGISTRY_IMAGE} + DOCKERFILE := Dockerfile +endif + +$(BUILD_DIR): + mkdir $(BUILD_DIR) + +.PHONY: build-linux $(BUILD_DIR) +build-linux: makefiles prebuild-check deps ## Builds the Linux binary for the container image into bin/ folder + CGO_ENABLED=0 GOARCH=amd64 GOOS=linux go build -v $(LDFLAGS) -o $(BUILD_DIR)/$(PROJECT_NAME) + +image: clean-artifacts build-linux + docker build -t $(REGISTRY_URL) \ + --build-arg BUILD_DIR=$(BUILD_DIR)\ + --build-arg PROJECT_NAME=$(PROJECT_NAME)\ + -f $(VENDOR_DIR)/github.com/fabric8-services/fabric8-common/makefile/$(DOCKERFILE) . + +# ------------------------------------------------------------------- +# help! +# ------------------------------------------------------------------- + +.PHONY: help +# Based on https://gist.github.com/rcmachado/af3db315e31383502660 +## Display this help text +help:/ + $(info Available targets) + $(info -----------------) + @awk '/^[a-zA-Z\-\_0-9]+:/ { \ + helpMessage = match(lastLine, /^## (.*)/); \ + helpCommand = substr($$1, 0, index($$1, ":")-1); \ + if (helpMessage) { \ + helpMessage = substr(lastLine, RSTART + 3, RLENGTH); \ + gsub(/##/, "\n ", helpMessage); \ + printf "%-35s - %s\n", helpCommand, helpMessage; \ + lastLine = "" \ + } \ + } \ + { hasComment = match(lastLine, /^## (.*)/); \ + if(hasComment) { \ + lastLine=lastLine$$0; \ + } \ + else { \ + lastLine = $$0 \ + } \ + }' $(MAKEFILE_LIST) +# ------------------------------------------------------------------- +# required tools +# ------------------------------------------------------------------- + +# Find all required tools: +GIT_BIN := $(shell command -v $(GIT_BIN_NAME) 2> /dev/null) +TMP_BIN_DIR := $(TMP_PATH)/bin +DEP_BIN := $(TMP_BIN_DIR)/$(DEP_BIN_NAME) +DEP_VERSION=v0.5.0 +GOLANGCI_LINT_VERSION=1.12 +GOLANGCI_LINT_BIN=$(TMP_BIN_DIR)/$(GOLANGCI_LINT_BIN_NAME) +GO_BIN := $(shell command -v $(GO_BIN_NAME) 2> /dev/null) + +$(INSTALL_PREFIX): + mkdir -p $(INSTALL_PREFIX) +$(TMP_PATH): + mkdir -p $(TMP_PATH) + +.PHONY: prebuild-check +prebuild-check: $(TMP_PATH) $(INSTALL_PREFIX) +# Check that all tools where found +ifndef GIT_BIN + $(error The "$(GIT_BIN_NAME)" executable could not be found in your PATH) +endif +ifndef DEP_BIN + $(error The "$(DEP_BIN_NAME)" executable could not be found in your PATH) +endif +ifndef GO_BIN + $(error The "$(GO_BIN_NAME)" executable could not be found in your PATH) +endif + +# ------------------------------------------------------------------- +# deps +# ------------------------------------------------------------------- + +.PHONY: deps +## Download build dependencies +deps: $(DEP_BIN) $(VENDOR_DIR) + +# install dep in a the tmp/bin dir of the repo +$(DEP_BIN): + @echo "Installing 'dep' $(DEP_VERSION) at '$(TMP_BIN_DIR)'..." + mkdir -p $(TMP_BIN_DIR) +ifeq ($(UNAME_S),Darwin) + @curl -L -s https://github.com/golang/dep/releases/download/$(DEP_VERSION)/dep-darwin-amd64 -o $(DEP_BIN) + @cd $(TMP_BIN_DIR) && \ + curl -L -s https://github.com/golang/dep/releases/download/$(DEP_VERSION)/dep-darwin-amd64.sha256 -o $(TMP_BIN_DIR)/dep-darwin-amd64.sha256 && \ + echo "1a7bdb0d6c31ecba8b3fd213a1170adf707657123e89dff234871af9e0498be2 dep" > dep-darwin-amd64.sha256 && \ + shasum -a 256 --check dep-darwin-amd64.sha256 +else + @curl -L -s https://github.com/golang/dep/releases/download/$(DEP_VERSION)/dep-linux-amd64 -o $(DEP_BIN) + @cd $(TMP_BIN_DIR) && \ + echo "287b08291e14f1fae8ba44374b26a2b12eb941af3497ed0ca649253e21ba2f83 dep" > dep-linux-amd64.sha256 && \ + sha256sum -c dep-linux-amd64.sha256 +endif + @chmod +x $(DEP_BIN) + +$(VENDOR_DIR): Gopkg.toml + @echo "checking dependencies with $(DEP_BIN_NAME)" + @$(DEP_BIN) ensure -v + +# ------------------------------------------------------------------- +# Code format/check +# ------------------------------------------------------------------- +GOFORMAT_FILES := $(shell find . -name '*.go' | grep -vEf $(INCLUDE_DIR)/gofmt_exclude) + +.PHONY: check-go-format +## Exits with an error if there are files that do not match formatting defined by gofmt +check-go-format: prebuild-check deps + @gofmt -s -l ${GOFORMAT_FILES} 2>&1 \ + | tee /tmp/gofmt-errors \ + | read \ + && echo "ERROR: These files differ from gofmt's style (run 'make format-go-code' to fix this):" \ + && cat /tmp/gofmt-errors \ + && exit 1 \ + || true + +.PHONY: analyze-go-code +## Run golangci analysis over the code +analyze-go-code: deps + $(info >>--- RESULTS: GOLANGCI CODE ANALYSIS ---<<) + @go get -u github.com/golangci/golangci-lint/cmd/golangci-lint + @golangci-lint run + +.PHONY: format-go-code +## Formats any go file that does not match formatting defined by gofmt +format-go-code: prebuild-check + @gofmt -s -l -w ${GOFORMAT_FILES} + +# ------------------------------------------------------------------- +# Code format/check with golangci-lint +# ------------------------------------------------------------------- +.PHONY: check-go-code +## Checks the code with golangci-lint +check-go-code: $(GOLANGCI_LINT_BIN) + @echo "checking code..." + $(GOLANGCI_LINT_BIN) run + +# install golangci-lint in the 'tmp/bin' dir of the repo +$(GOLANGCI_LINT_BIN): + @echo "Installing 'golang-ci-lint' $(GOLANGCI_LINT_VERSION) at '$(TMP_BIN_DIR)' ..." + mkdir -p $(TMP_BIN_DIR) +ifeq ($(UNAME_S),Darwin) + @curl -L -s https://github.com/golangci/golangci-lint/releases/download/v$(GOLANGCI_LINT_VERSION)/golangci-lint-$(GOLANGCI_LINT_VERSION)-darwin-amd64.tar.gz -o $(GOLANGCI_LINT_BIN)-$(GOLANGCI_LINT_VERSION)-darwin-amd64.tar.gz && \ + cd $(TMP_BIN_DIR) && curl -L -s https://github.com/golangci/golangci-lint/releases/download/v$(GOLANGCI_LINT_VERSION)/golangci-lint-$(GOLANGCI_LINT_VERSION)-checksums.txt -o golangci-lint-$(GOLANGCI_LINT_VERSION)-checksums.txt && \ + grep "darwin-amd64" golangci-lint-$(GOLANGCI_LINT_VERSION)-checksums.txt > golangci-lint-$(GOLANGCI_LINT_VERSION)-checksum-darwin-amd64.txt && \ + shasum -a 256 --check golangci-lint-$(GOLANGCI_LINT_VERSION)-checksum-darwin-amd64.txt && \ + tar xvf $(GOLANGCI_LINT_BIN)-$(GOLANGCI_LINT_VERSION)-darwin-amd64.tar.gz -C $(TMP_BIN_DIR) && \ + mv $(TMP_BIN_DIR)/golangci-lint-$(GOLANGCI_LINT_VERSION)-darwin-amd64/golangci-lint $(GOLANGCI_LINT_BIN) +else + @curl -L -s https://github.com/golangci/golangci-lint/releases/download/v$(GOLANGCI_LINT_VERSION)/golangci-lint-$(GOLANGCI_LINT_VERSION)-linux-amd64.tar.gz -o $(GOLANGCI_LINT_BIN)-$(GOLANGCI_LINT_VERSION)-linux-amd64.tar.gz && \ + cd $(TMP_BIN_DIR) && curl -L -s https://github.com/golangci/golangci-lint/releases/download/v$(GOLANGCI_LINT_VERSION)/golangci-lint-$(GOLANGCI_LINT_VERSION)-checksums.txt -o golangci-lint-$(GOLANGCI_LINT_VERSION)-checksums.txt && \ + grep "linux-amd64" golangci-lint-$(GOLANGCI_LINT_VERSION)-checksums.txt > golangci-lint-$(GOLANGCI_LINT_VERSION)-checksum-linux-amd64.txt && \ + sha256sum -c golangci-lint-$(GOLANGCI_LINT_VERSION)-checksum-linux-amd64.txt && \ + tar xvf $(GOLANGCI_LINT_BIN)-$(GOLANGCI_LINT_VERSION)-linux-amd64.tar.gz -C $(TMP_BIN_DIR) && \ + mv $(TMP_BIN_DIR)/golangci-lint-$(GOLANGCI_LINT_VERSION)-linux-amd64/golangci-lint $(GOLANGCI_LINT_BIN) +endif + @chmod +x $(GOLANGCI_LINT_BIN) + + +# ------------------------------------------------------------------- +# clean +# ------------------------------------------------------------------- + +# For the global "clean" target all targets in this variable will be executed +CLEAN_TARGETS = + +CLEAN_TARGETS += clean-artifacts +.PHONY: clean-artifacts +# Removes the ./bin directory. +clean-artifacts: + -rm -rf $(INSTALL_PREFIX) + +CLEAN_TARGETS += clean-object-files +.PHONY: clean-object-files +# Runs go clean to remove any executables or other object files. +clean-object-files: + go clean ./... + +CLEAN_TARGETS += clean-vendor +.PHONY: clean-vendor +# Removes the ./vendor directory. +clean-vendor: + -rm -rf $(VENDOR_DIR) + +CLEAN_TARGETS += clean-tmp +.PHONY: clean-tmp +# Removes the ./vendor directory. +clean-tmp: + -rm -rf $(TMP_PATH) + +# Keep this "clean" target here after all `clean-*` sub tasks +.PHONY: clean +## Cleans the project, removes all generated code/bins and vendor packages +clean: $(CLEAN_TARGETS) + +# ------------------------------------------------------------------- +# build the binary executable (to ship in prod) +# ------------------------------------------------------------------- + +.PHONY: build +## Build git service +build: prebuild-check deps check-go-format + @echo "building $(BINARY_SERVER_BIN)..." + go build -v -o $(BINARY_SERVER_BIN) pkg/cmd/main.go diff --git a/deploy/apiservice.yaml b/deploy/apiservice.yaml new file mode 100644 index 0000000..4770291 --- /dev/null +++ b/deploy/apiservice.yaml @@ -0,0 +1,13 @@ +apiVersion: apiregistration.k8s.io/v1beta1 +kind: APIService +metadata: + name: v1alpha1.gitservice.devopsconsole.openshift.io +spec: + insecureSkipTLSVerify: true + group: gitservice.devopsconsole.openshift.io + groupPriorityMinimum: 1000 + versionPriority: 15 + service: + name: api + namespace: openshift-devops-console + version: v1alpha1 diff --git a/deploy/git-api-server-deployment.yaml b/deploy/git-api-server-deployment.yaml new file mode 100644 index 0000000..a60754d --- /dev/null +++ b/deploy/git-api-server-deployment.yaml @@ -0,0 +1,41 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: git-service + namespace: openshift-devops-console + labels: + apiserver: "true" +spec: + replicas: 1 + selector: + matchLabels: + name: git-service + apiserver: "true" + template: + metadata: + labels: + name: git-service + apiserver: "true" + spec: + serviceAccountName: gitapiserver + containers: + - name: git-service + # Replace this with the built image name + image: quay.io/openshiftio/git-service:dev + imagePullPolicy: Always + command: [ "/git-service", "--etcd-servers=http://localhost:2379" ] + volumeMounts: + - mountPath: /tmp/kube-apiserver-audit.log + name: audit-log + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: etcd + image: quay.io/coreos/etcd:v3.2.18 + volumes: + - name: audit-log + hostPath: + path: /tmp/kube-apiserver-audit.log + type: FileOrCreate diff --git a/deploy/grant-auth-delegator.yaml b/deploy/grant-auth-delegator.yaml new file mode 100644 index 0000000..ac8f3dc --- /dev/null +++ b/deploy/grant-auth-delegator.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: gitservice-devopsconsole:system:auth-delegator +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:auth-delegator +subjects: +- kind: ServiceAccount + name: gitapiserver + namespace: openshift-devops-console diff --git a/deploy/grant-auth-reader.yaml b/deploy/grant-auth-reader.yaml new file mode 100644 index 0000000..41d09ab --- /dev/null +++ b/deploy/grant-auth-reader.yaml @@ -0,0 +1,13 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: gitservice-devopsconsole-auth-reader + namespace: kube-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: extension-apiserver-authentication-reader +subjects: +- kind: ServiceAccount + name: gitapiserver + namespace: openshift-devops-console diff --git a/deploy/grant-cluster-admin.yaml b/deploy/grant-cluster-admin.yaml new file mode 100644 index 0000000..b44785b --- /dev/null +++ b/deploy/grant-cluster-admin.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: gitservice-devopsconsole:cluster-admin +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cluster-admin +subjects: +- kind: ServiceAccount + name: gitapiserver + namespace: openshift-devops-console diff --git a/deploy/namespace.yaml b/deploy/namespace.yaml new file mode 100644 index 0000000..ac5fc18 --- /dev/null +++ b/deploy/namespace.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: openshift-devops-console +spec: diff --git a/deploy/service.yaml b/deploy/service.yaml new file mode 100644 index 0000000..cea22ec --- /dev/null +++ b/deploy/service.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Service +metadata: + name: api + namespace: openshift-devops-console +spec: + ports: + - port: 443 + protocol: TCP + targetPort: 443 + selector: + apiserver: "true" diff --git a/deploy/service_account.yaml b/deploy/service_account.yaml new file mode 100644 index 0000000..cd87bff --- /dev/null +++ b/deploy/service_account.yaml @@ -0,0 +1,5 @@ +kind: ServiceAccount +apiVersion: v1 +metadata: + name: gitapiserver + namespace: openshift-devops-console diff --git a/make/Makefile.dev b/make/Makefile.dev new file mode 100644 index 0000000..f73a88b --- /dev/null +++ b/make/Makefile.dev @@ -0,0 +1,88 @@ +DOCKER_REPO?=quay.io/openshiftio +IMAGE_NAME?=git-service +SHORT_COMMIT=$(shell git rev-parse --short HEAD) +ifneq ($(GITUNTRACKEDCHANGES),) +SHORT_COMMIT := $(SHORT_COMMIT)-dirty +endif + +TIMESTAMP:=$(shell date +%s) +TAG?=$(SHORT_COMMIT)-$(TIMESTAMP) + +DEPLOY_DIR:=deploy + +.PHONY: create-resources +create-resources: + @echo "Logging using system:admin..." + @oc login -u system:admin + @echo "Creating sub resources..." + @echo "Creating CRDs..." + @oc create -f https://raw.githubusercontent.com/redhat-developer/devopsconsole-operator/master/deploy/crds/devopsconsole_v1alpha1_gitsource_crd.yaml + @echo "Creating Namespace" + @oc create -f $(DEPLOY_DIR)/namespace.yaml + @echo "oc project openshift-devops-console" + @oc project openshift-devops-console + @echo "Creating Service Account" + @oc create -f $(DEPLOY_DIR)/service_account.yaml + @echo "Granting system:auth-delegator Role" + @oc create -f $(DEPLOY_DIR)/grant-auth-delegator.yaml -n kube-system + @echo "Granting extension-apiserver-authentication-reader Role" + @oc create -f $(DEPLOY_DIR)/grant-auth-reader.yaml -n kube-system + @echo "Granting Cluster Admin Role" + @oc create -f $(DEPLOY_DIR)/grant-cluster-admin.yaml + +.PHONY: create-cr +create-cr: + @echo "Creating Custom Resource..." + +.PHONY: build-image +build-image: + docker build -t $(DOCKER_REPO)/$(IMAGE_NAME):$(TAG) -f Dockerfile.dev . + docker tag $(DOCKER_REPO)/$(IMAGE_NAME):$(TAG) $(DOCKER_REPO)/$(IMAGE_NAME):test + +.PHONY: deploy-apiserver-only +deploy-apiserver-only: + @echo "Creating Replication Controller for API Server" + @cat minishift/git-api-server-deployment.yaml | sed s/\:dev/:$(TAG)/ | oc create -f - + @echo "Creating Service" + @oc create -f $(DEPLOY_DIR)/service.yaml + @echo "Creating API Service" + @oc create -f $(DEPLOY_DIR)/apiservice.yaml + +.PHONY: clean-all +clean-all: clean-apiserver clean-resources + +.PHONY: clean-apiserver +clean-apiserver: + @echo "Deleting Replication Controller for API Server" + @cat minishift/git-api-server-deployment.yaml | sed s/\:dev/:$(TAG)/ | oc delete -f - || true + @echo "Deleting Service" + @oc delete -f $(DEPLOY_DIR)/service.yaml || true + @echo "Deleting API Service" + @oc delete -f $(DEPLOY_DIR)/apiservice.yaml || true + +.PHONY: clean-resources +clean-resources: + @echo "Deleting sub resources..." + @echo "Deleting Cluster Admin Role" + @oc delete -f $(DEPLOY_DIR)/grant-cluster-admin.yaml || true + @echo "Deleting extension-apiserver-authentication-reader Role" + @oc delete -f $(DEPLOY_DIR)/grant-auth-reader.yaml -n kube-system || true + @echo "Deleting system:auth-delegator Role" + @oc delete -f $(DEPLOY_DIR)/grant-auth-delegator.yaml -n kube-system || true + @echo "Deleting Service Account" + @oc delete -f $(DEPLOY_DIR)/service_account.yaml || true + @echo "Deleting Namespace" + @oc delete -f $(DEPLOY_DIR)/namespace.yaml || true + @echo "Deleting CRDs..." + @oc delete -f https://raw.githubusercontent.com/redhat-developer/devopsconsole-operator/master/deploy/crds/devopsconsole_v1alpha1_gitsource_crd.yaml || true + +.PHONY: deploy-apiserver +deploy-apiserver: build build-image deploy-apiserver-only + +.PHONY: minishift-start +minishift-start: + minishift start --cpus 4 --memory 8GB + -eval `minishift docker-env` && oc login -u system:admin + +.PHONY: deploy-all +deploy-all: clean-resources create-resources deps prebuild-check deploy-apiserver create-cr diff --git a/make/docker.mk b/make/docker.mk new file mode 100644 index 0000000..84e5322 --- /dev/null +++ b/make/docker.mk @@ -0,0 +1,108 @@ +DOCKER_IMAGE_CORE := $(PROJECT_NAME) +DOCKER_IMAGE_DEPLOY := $(PROJECT_NAME)-deploy + +ifeq ($(TARGET),rhel) + DOCKERFILE_DEPLOY := Dockerfile.deploy.rhel +else + DOCKERFILE_DEPLOY := Dockerfile.deploy +endif + +# If running in Jenkins we don't allow for interactively running the container +ifneq ($(BUILD_TAG),) + DOCKER_RUN_INTERACTIVE_SWITCH := +else + DOCKER_RUN_INTERACTIVE_SWITCH := -i +endif + +# The workspace environment is set by Jenkins and defaults to /tmp if not set +WORKSPACE ?= /tmp +DOCKER_BUILD_DIR := $(WORKSPACE)/$(PROJECT_NAME)-build + +# The BUILD_TAG environment variable will be set by jenkins +# to reflect jenkins-${JOB_NAME}-${BUILD_NUMBER} +BUILD_TAG ?= $(PROJECT_NAME)-local-build +DOCKER_CONTAINER_NAME := $(BUILD_TAG) + +# Where is the GOPATH inside the build container? +GOPATH_IN_CONTAINER=/tmp/go +PACKAGE_PATH=$(GOPATH_IN_CONTAINER)/src/$(PACKAGE_NAME) + +.PHONY: docker-image-builder +## Builds the docker image used to build the software +docker-image-builder: + @echo "Building docker image $(DOCKER_IMAGE_CORE)" + docker build --build-arg USE_GO_VERSION_FROM_WEBSITE=$(USE_GO_VERSION_FROM_WEBSITE) -t $(DOCKER_IMAGE_CORE) -f $(CUR_DIR)/Dockerfile.builder $(CUR_DIR) + +.PHONY: docker-image-deploy +## Creates a runnable image using the artifacts from the bin directory +docker-image-deploy: + docker build -t $(DOCKER_IMAGE_DEPLOY) -f $(CUR_DIR)/$(DOCKERFILE_DEPLOY) $(CUR_DIR) + +.PHONY: docker-build-dir +# Creates the docker build directory. +docker-build-dir: + @echo "Creating build directory $(BUILD_DIR)" + mkdir -p $(DOCKER_BUILD_DIR) + +CLEAN_TARGETS += clean-docker-build-container +.PHONY: clean-docker-build-container +# Removes any existing container used to build the software (if any). +clean-docker-build-container: + @echo "Removing container named \"$(DOCKER_CONTAINER_NAME)\" (if any)" +ifneq ($(strip $(shell docker ps -qa --filter "name=$(DOCKER_CONTAINER_NAME)" 2>/dev/null)),) + @docker rm -f $(DOCKER_CONTAINER_NAME) +else + @echo "No container named \"$(DOCKER_CONTAINER_NAME)\" to remove" +endif + +CLEAN_TARGETS += clean-docker-build-dir +.PHONY: clean-docker-build-dir +# Removes the docker build directory. +clean-docker-build-dir: + @echo "Cleaning build directory $(BUILD_DIR)" + -rm -rf $(DOCKER_BUILD_DIR) + +.PHONY: docker-start +## Starts the docker build container in the background (detached mode). +## After calling this command you can invoke all the make targets from the +## normal Makefile (e.g. deps, build) inside the build container +## by prefixing them with "docker-". For example to execute "make deps" +## inside the build container, just run "make docker-deps". +## To remove the container when no longer needed, call "make docker-rm". +docker-start: docker-build-dir docker-image-builder +ifneq ($(strip $(shell docker ps -qa --filter "name=$(DOCKER_CONTAINER_NAME)" 2>/dev/null)),) + @echo "Docker container \"$(DOCKER_CONTAINER_NAME)\" already exists. To recreate, run \"make docker-rm\"." +else + docker run \ + --detach=true \ + -t \ + $(DOCKER_RUN_INTERACTIVE_SWITCH) \ + --name="$(DOCKER_CONTAINER_NAME)" \ + -e ADMIN_POSTGRES_PORT=5432 \ + -v $(CUR_DIR):$(PACKAGE_PATH):Z \ + -u $(shell id -u $(USER)):$(shell id -g $(USER)) \ + -e GOPATH=$(GOPATH_IN_CONTAINER) \ + -w $(PACKAGE_PATH) \ + $(DOCKER_IMAGE_CORE) + @echo "Docker container \"$(DOCKER_CONTAINER_NAME)\" created. Continue with \"make docker-deps\"." +endif + +.PHONY: docker-rm +# Removes the docker build container, if any (see "make docker-start"). +docker-rm: +ifneq ($(strip $(shell docker ps -qa --filter "name=$(DOCKER_CONTAINER_NAME)" 2>/dev/null)),) + docker rm -f "$(DOCKER_CONTAINER_NAME)" +else + @echo "No container named \"$(DOCKER_CONTAINER_NAME)\" to remove." +endif + +# This is a wildcard target to let you call any make target from the normal makefile +# but it will run inside the docker container. This target will only get executed if +# there's no specialized form available. For example if you call "make docker-start" +# not this target gets executed but the "docker-start" target. +docker-%: + $(eval makecommand:=$(subst docker-,,$@)) +ifeq ($(strip $(shell docker ps -qa --filter "name=$(DOCKER_CONTAINER_NAME)" 2>/dev/null)),) + $(error No container name "$(DOCKER_CONTAINER_NAME)" exists to run the command "make $(makecommand)") +endif + docker exec -t $(DOCKER_RUN_INTERACTIVE_SWITCH) "$(DOCKER_CONTAINER_NAME)" bash -ec 'make $(makecommand)' diff --git a/make/gofmt_exclude b/make/gofmt_exclude new file mode 100644 index 0000000..6d03c3e --- /dev/null +++ b/make/gofmt_exclude @@ -0,0 +1 @@ +vendor/.* diff --git a/make/test.mk b/make/test.mk new file mode 100644 index 0000000..bd1fc5c --- /dev/null +++ b/make/test.mk @@ -0,0 +1,347 @@ +#=============================================================================== +# Testing has become a rather big and interconnected topic and that's why it +# has arrived in it's own file. +# +# We have to types of tests available: +# +# 1. unit tests +# +# The unit tests can be executed fairly simply be running `go test` +# +# Usage +# ----- +# If you want to run the unit tests, type +# +# $ make test-unit +# +# To run all tests, type +# +# $ make test-all +# +# To output unit-test coverage profile information for each function, type +# +# $ make coverage-unit +# +# To generate unit-test HTML representation of coverage profile (opens a browser), type +# +# $ make coverage-unit-html +# +# To output all coverage profile information for each function, type +# +# $ make coverage-all +# +# Artifacts and coverage modes +# ---------------------------- +# Each package generates coverage outputs under tmp/coverage/$(PACKAGE) where +# $(PACKAGE) resolves to the Go package. Here's an example of a coverage file +# for the package "github.com/fabric8-services/fabric8-auth/models" with coverage mode +# "set" generated by the unit tests: +# +# tmp/coverage/github.com/fabric8-services/fabric8-auth/models/coverage.unit.mode-set +# +# For unit-tests all results are combined into this file: +# +# tmp/coverage.unit.mode-$(COVERAGE_MODE) +# +# +# The overall coverage gets combined into this file: +# +# tmp/coverage.mode-$(COVERAGE_MODE) +# +# The $(COVERAGE_MODE) in each filename indicates what coverage mode was used. +# +# These are possible coverage modes (see https://blog.golang.org/cover): +# +# set: did each statement run? (default) +# count: how many times did each statement run? +# atomic: like count, but counts precisely in parallel programs +# +# To choose another coverage mode, simply prefix the invovation of `make`: +# +# $ COVERAGE_MODE=count make test-unit +#=============================================================================== + +# mode can be: set, count, or atomic +COVERAGE_MODE ?= set + +# By default no go test calls will use the -v switch when running tests. +# But if you want you can enable that by setting GO_TEST_VERBOSITY_FLAG=-v +GO_TEST_VERBOSITY_FLAG ?= + + +# By default reduce the amount of log output from tests +ADMIN_LOG_LEVEL ?= error + +# Output directory for coverage information +COV_DIR = $(TMP_PATH)/coverage + +# Files that combine package coverages for unit tests separately +COV_PATH_UNIT = $(TMP_PATH)/coverage.unit.mode-$(COVERAGE_MODE) + +# File that stores overall coverge for all packages and unit-tests +COV_PATH_OVERALL = $(TMP_PATH)/coverage.mode-$(COVERAGE_MODE) + +# This pattern excludes some folders from the coverage calculation (see grep -v) +ALL_PKGS_EXCLUDE_PATTERN = 'vendor\|app\|tool\/cli\|design\|client\|test' + +# This pattern excludes some folders from the go code analysis +GOANALYSIS_PKGS_EXCLUDE_PATTERN="vendor|app|client|tool/cli" +GOANALYSIS_DIRS=$(shell go list -f {{.Dir}} ./... | grep -v -E $(GOANALYSIS_PKGS_EXCLUDE_PATTERN)) + +#------------------------------------------------------------------------------- +# Normal test targets +# +# These test targets are the ones that will be invoked from the outside. If +# they are called and the artifacts already exist, then the artifacts will +# first be cleaned and recreated. This ensures that the tests are always +# executed. +#------------------------------------------------------------------------------- + +.PHONY: test-all +## Runs the unit tests and e2e tests +test-all: prebuild-check test-unit test-e2e + +# Runs the unit tests and produces coverage files for each package. +.PHONY: test-unit-with-coverage +test-unit-with-coverage: prebuild-check clean-coverage-unit $(COV_PATH_UNIT) + +.PHONY: test-unit +## Runs the unit tests without coverage +test-unit: prebuild-check $(SOURCES) + $(call log-info,"Running test: $@") + $(eval TEST_PACKAGES:=$(shell go list ./... | grep -v $(ALL_PKGS_EXCLUDE_PATTERN))) + ADMIN_LOG_LEVEL=$(ADMIN_LOG_LEVEL) go test -vet off $(GO_TEST_VERBOSITY_FLAG) $(TEST_PACKAGES) + +.PHONY: test-e2e +## Runs the e2e tests without coverage +test-e2e: build build-image e2e-setup + $(call log-info,"Running E2E test: $@") + go test ./test/e2e/... -root=$(PWD) -kubeconfig=$(HOME)/.kube/config -globalMan deploy/test/global-manifests.yaml -namespacedMan deploy/test/namespace-manifests.yaml -v -parallel=1 -singleNamespace + +.PHONY: e2e-setup +e2e-setup: e2e-cleanup + oc new-project devconsole-e2e-test || true + +.PHONY: e2e-cleanup +e2e-cleanup: + oc login -u system:admin + oc delete project devconsole-e2e-test || true + +#------------------------------------------------------------------------------- +# Inspect coverage of unit tests, integration tests in either pure +# console mode or in a browser (*-html). +# +# If the test coverage files to be evaluated already exist, then no new +# tests are executed. If they don't exist, we first run the tests. +#------------------------------------------------------------------------------- + +# Prints the total coverage of a given package. +# The total coverage is printed as the last argument in the +# output of "go tool cover". If the requested test name (first argument) +# Is *, then unit, integration tests will be combined +define print-package-coverage +$(eval TEST_NAME:=$(1)) +$(eval PACKAGE_NAME:=$(2)) +$(eval COV_FILE:="$(COV_DIR)/$(PACKAGE_NAME)/coverage.$(TEST_NAME).mode-$(COVERAGE_MODE)") + @if [ "$(TEST_NAME)" == "*" ]; then \ + UNIT_FILE=`echo $(COV_FILE) | sed 's/*/unit/'`; \ + INTEGRATON_FILE=`echo $(COV_FILE) | sed 's/*/integration/'`; \ + COV_FILE=`echo $(COV_FILE) | sed 's/*/combined/'`; \ + if [ ! -e $${UNIT_FILE} ]; then \ + COV_FILE=$${INTEGRATION_FILE}; \ + else \ + if [ ! -e $${INTEGRATION_FILE} ]; then \ + COV_FILE=$${UNIT_FILE}; \ + else \ + $(GOCOVMERGE_BIN) $${UNIT_FILE} $${INTEGRATION_FILE} > $${COV_FILE}; \ + fi; \ + fi; \ +else \ + COV_FILE=$(COV_FILE); \ +fi; \ +if [ -e "$${COV_FILE}" ]; then \ + VAL=`go tool cover -func=$${COV_FILE} \ + | grep '^total:' \ + | grep '\S\+$$' -o \ + | sed 's/%//'`; \ + printf "%-80s %#5.2f%%\n" "$(PACKAGE_NAME)" "$${VAL}"; \ +else \ + printf "%-80s %6s\n" "$(PACKAGE_NAME)" "n/a"; \ +fi +endef + +# Iterates over every package and prints its test coverage +# for a given test name ("unit"). +define package-coverage +$(eval TEST_NAME:=$(1)) +@printf "\n\nPackage coverage:\n" +$(eval TEST_PACKAGES:=$(shell go list ./... | grep -v $(ALL_PKGS_EXCLUDE_PATTERN))) +$(foreach package, $(TEST_PACKAGES), $(call print-package-coverage,$(TEST_NAME),$(package))) +endef + +$(COV_PATH_OVERALL): $(GOCOVMERGE_BIN) + @$(GOCOVMERGE_BIN) $(COV_PATH_UNIT) > $(COV_PATH_OVERALL) + +# Console coverage output: + +# First parameter: file to do in-place replacement with. +define cleanup-coverage-file +@sed -i '/.*\/sqlbindata\.go.*/d' $(1) +@sed -i '/.*\/confbindata\.go.*/d' $(1) +endef + +# Output coverage profile information for each function (only based on unit-tests). +# Re-runs unit-tests if coverage information is outdated. +.PHONY: coverage-unit +## Runs the unit tests with producing coverage files for each package +coverage-unit: prebuild-check $(COV_PATH_UNIT) + $(call cleanup-coverage-file,$(COV_PATH_UNIT)) + @go tool cover -func=$(COV_PATH_UNIT) + $(call package-coverage,unit) + + +.PHONY: coverage-all +# Output coverage profile information for each function. +# Re-runs unit- and integration-tests if coverage information is outdated. +coverage-all: prebuild-check clean-coverage-overall $(COV_PATH_OVERALL) + $(call cleanup-coverage-file,$(COV_PATH_OVERALL)) + @go tool cover -func=$(COV_PATH_OVERALL) + $(call package-coverage,*) + +# HTML coverage output: + +# Generate HTML representation (and show in browser) of coverage profile (based on unit tests). +# Re-runs unit tests if coverage information is outdated. +.PHONY: coverage-unit-html +## Runs the unit tests with producing coverage html for each package +coverage-unit-html: prebuild-check $(COV_PATH_UNIT) + $(call cleanup-coverage-file,$(COV_PATH_UNIT)) + @go tool cover -html=$(COV_PATH_UNIT) + +.PHONY: coverage-all-html +# Output coverage profile information for each function. +# Re-runs unit if coverage information is outdated. +coverage-all-html: prebuild-check clean-coverage-overall $(COV_PATH_OVERALL) + $(call cleanup-coverage-file,$(COV_PATH_OVERALL)) + @go tool cover -html=$(COV_PATH_OVERALL) + +# Experimental: + +.PHONY: gocov-unit-annotate +# (EXPERIMENTAL) Show actual code and how it is covered with unit tests. +# This target only runs the tests if the coverage file does exist. +gocov-unit-annotate: prebuild-check $(GOCOV_BIN) $(COV_PATH_UNIT) + $(call cleanup-coverage-file,$(COV_PATH_UNIT)) + @$(GOCOV_BIN) convert $(COV_PATH_UNIT) | $(GOCOV_BIN) annotate - + +.PHONY: .gocov-unit-report +.gocov-unit-report: prebuild-check $(GOCOV_BIN) $(COV_PATH_UNIT) + $(call cleanup-coverage-file,$(COV_PATH_UNIT)) + @$(GOCOV_BIN) convert $(COV_PATH_UNIT) | $(GOCOV_BIN) report + + +#------------------------------------------------------------------------------- +# Test artifacts are coverage files for unit and integration tests. +#------------------------------------------------------------------------------- + +# The test-package function executes tests for a package and saves the collected +# coverage output to a directory. After storing the coverage information it is +# also appended to a file of choice (without the "mode"-line) +# +# Parameters: +# 1. Test name (e.g. "unit" or "integration") +# 2. package name "github.com/fabric8-services/fabric8-auth/model" +# 3. File in which to combine the output +# 4. Path to file in which to store names of packages that failed testing +# 5. Environment variable (in the form VAR=VALUE) to be specified for running +# the test. For multiple environment variables, pass "VAR1=VAL1 VAR2=VAL2". +define test-package +$(eval TEST_NAME := $(1)) +$(eval PACKAGE_NAME := $(2)) +$(eval COMBINED_OUT_FILE := $(3)) +$(eval ERRORS_FILE := $(4)) +$(eval ENV_VAR := $(5)) +$(eval ALL_PKGS_COMMA_SEPARATED := $(6)) +@mkdir -p $(COV_DIR)/$(PACKAGE_NAME); +$(eval COV_OUT_FILE := $(COV_DIR)/$(PACKAGE_NAME)/coverage.$(TEST_NAME).mode-$(COVERAGE_MODE)) +@$(ENV_VAR) ADMIN_LOG_LEVEL=$(ADMIN_LOG_LEVEL) \ + go test -vet off $(PACKAGE_NAME) \ + $(GO_TEST_VERBOSITY_FLAG) \ + -coverprofile $(COV_OUT_FILE) \ + -coverpkg $(ALL_PKGS_COMMA_SEPARATED) \ + -covermode=$(COVERAGE_MODE) \ + -timeout 10m \ + $(EXTRA_TEST_PARAMS) \ + || echo $(PACKAGE_NAME) >> $(ERRORS_FILE) + +@if [ -e "$(COV_OUT_FILE)" ]; then \ + if [ ! -e "$(COMBINED_OUT_FILE)" ]; then \ + cp $(COV_OUT_FILE) $(COMBINED_OUT_FILE); \ + else \ + cp $(COMBINED_OUT_FILE) $(COMBINED_OUT_FILE).tmp; \ + $(GOCOVMERGE_BIN) $(COV_OUT_FILE) $(COMBINED_OUT_FILE).tmp > $(COMBINED_OUT_FILE); \ + fi \ +fi +endef + +# Exits the makefile with an error if the file (first parameter) exists. +# Before exiting, the contents of the passed file is printed. +define check-test-results +$(eval ERRORS_FILE := $(1)) +@if [ -e "$(ERRORS_FILE)" ]; then \ +echo ""; \ +echo "ERROR: The following packages did not pass the tests:"; \ +echo "-----------------------------------------------------"; \ +cat $(ERRORS_FILE); \ +echo "-----------------------------------------------------"; \ +echo ""; \ +exit 1; \ +fi +endef + +# NOTE: We don't have prebuild-check as a dependency here because it would cause +# the recipe to be always executed. +$(COV_PATH_UNIT): $(SOURCES) $(GOCOVMERGE_BIN) + $(eval TEST_NAME := unit) + $(eval ERRORS_FILE := $(TMP_PATH)/errors.$(TEST_NAME)) + $(call log-info,"Running test: $(TEST_NAME)") + @mkdir -p $(COV_DIR) + @echo "mode: $(COVERAGE_MODE)" > $(COV_PATH_UNIT) + @-rm -f $(ERRORS_FILE) + $(eval TEST_PACKAGES:=$(shell go list ./... | grep -v $(ALL_PKGS_EXCLUDE_PATTERN))) + $(eval ALL_PKGS_COMMA_SEPARATED:=$(shell echo $(TEST_PACKAGES) | tr ' ' ,)) + $(foreach package, $(TEST_PACKAGES), $(call test-package,$(TEST_NAME),$(package),$(COV_PATH_UNIT),$(ERRORS_FILE),,$(ALL_PKGS_COMMA_SEPARATED))) + $(call check-test-results,$(ERRORS_FILE)) + +#------------------------------------------------------------------------------- +# Additional tools to build +#------------------------------------------------------------------------------- + +$(GOCOV_BIN): prebuild-check + @cd $(VENDOR_DIR)/github.com/axw/gocov/gocov/ && go build + +$(GOCOVMERGE_BIN): prebuild-check + @cd $(VENDOR_DIR)/github.com/wadey/gocovmerge && go build + + +#------------------------------------------------------------------------------- +# Clean targets +#------------------------------------------------------------------------------- + +CLEAN_TARGETS += clean-coverage +.PHONY: clean-coverage +# Removes all coverage files +clean-coverage: clean-coverage-unit clean-coverage-overall + -@rm -rf $(COV_DIR) + +CLEAN_TARGETS += clean-coverage-overall +.PHONY: clean-coverage-overall +# Removes overall coverage file +clean-coverage-overall: + -@rm -f $(COV_PATH_OVERALL) + +CLEAN_TARGETS += clean-coverage-unit +.PHONY: clean-coverage-unit +# Removes unit test coverage file +clean-coverage-unit: + -@rm -f $(COV_PATH_UNIT) diff --git a/minishift/README.md b/minishift/README.md new file mode 100644 index 0000000..3a82af1 --- /dev/null +++ b/minishift/README.md @@ -0,0 +1,123 @@ +## Running Git Service on Minishift + +These instructions will help you run the service using MiniShift. + +### Prerequisites + +[MiniShift v1.27.0](https://docs.okd.io/latest/minishift/getting-started/installing.html) + +[oc 3.11.0](https://docs.okd.io/latest/cli_reference/get_started_cli.html#installing-the-cli) + +[KVM Hypervisor](https://www.linux-kvm.org/page/Downloads) + +#### Install Minishift + +Make sure you have all prerequisites installed. Please check the list [here](https://docs.openshift.org/latest/minishift/getting-started/installing.html#install-prerequisites) + +Download and put `minishift` in your $PATH by following steps [here](https://docs.openshift.org/latest/minishift/getting-started/installing.html#manually) + +Verify installation by running following command, you should get version number. +```bash +minishift version +``` + +#### Install oc +Please install and set up oc on your machine by visiting [oc](https://docs.okd.io/latest/cli_reference/get_started_cli.html#installing-the-cli) + +Verify installation by running following command, you should get version number. +```bash +oc version +``` + +### Usage +#### TL;DR +``` +make minishift-start +eval $(minishift docker-env) +make deploy-all +``` + +Make sure that you have minishift running. you can check it using `minishift status`. If not then start it using `make minishift-start` target. + +After successfully starting minishift, configure your shell to use docker daemon from minishift using `eval $(minishift docker-env)`. + +Now it's time to run `git-service` and it's required resources from `deploy/resources` on OpenShift use following command: +``` +make deploy-all +``` + +This build uses the `system:admin` account for creating all required resources from `deploy/resources` directory. + +The above command then create deployment for git-service on Openshift. + +#### Start Minishift +We have make target defined to start minishift with required cpu's and configuration. +```bash +make minishift-start +``` + +#### Exposing Docker Env +Make sure to expose minishift docker env using following command: +```bash +eval $(minishift docker-env) +``` + +After running this, you can verify all containers running container inside minishift using `docker ps`. + +**Note**: If you miss this, docker daemon inside minishift couldn't find latest built image which causes `ImagePullBackOff` as we are using `ImagePullPolicy: IfNotPresent` + + +### Creating resources required to run Git Service +To create required resources to run Git Service, we have following make target: +```bash +make create-resources +``` + +#### Build and Deploy Git Service +To build docker image and create deployment you can use following target: +```bash +make deploy-apiserver +``` + +#### Creating Custom Resource +To create Custom Resource, so that service can start it's functioning, you can use following target: +```bash +make create-cr +``` + +#### Creating Resources and Deploying Git Service +If you are too lazy, we have following target for you to create resources, build container and deploy service: + +```bash +make deploy-all +``` + +#### Cleaning Up + +##### Cleaning Git Service +This removes git service. +```bash +make clean-apiserver +``` + +##### Cleaning Resources Created to run Git Service +This removes all resources created to run git service. +```bash +make clean-resources +``` + +##### Cleaning Resources and Git Service +This removes all resources created to run git service along with git service itself. +```bash +make clean-all +``` + +#### ReDeploying Git Service with changes in code +However if you are working on git service code and wants to redeploy latest code change by building container with latest binary. We have +special target for it which will do that for you. + +It won't create all other existing resources again. It'll build container and deploy git service only. + +```bash +make deploy-apiserver +``` \ No newline at end of file diff --git a/minishift/git-api-server-deployment.yaml b/minishift/git-api-server-deployment.yaml new file mode 100644 index 0000000..2a467cb --- /dev/null +++ b/minishift/git-api-server-deployment.yaml @@ -0,0 +1,41 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: git-service + namespace: openshift-devops-console + labels: + apiserver: "true" +spec: + replicas: 1 + selector: + matchLabels: + name: git-service + apiserver: "true" + template: + metadata: + labels: + name: git-service + apiserver: "true" + spec: + serviceAccountName: gitapiserver + containers: + - name: git-service + # Replace this with the built image name + image: quay.io/openshiftio/git-service:dev + imagePullPolicy: IfNotPresent + command: [ "/git-service", "--etcd-servers=http://localhost:2379" ] + volumeMounts: + - mountPath: /tmp/kube-apiserver-audit.log + name: audit-log + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: etcd + image: quay.io/coreos/etcd:v3.2.18 + volumes: + - name: audit-log + hostPath: + path: /tmp/kube-apiserver-audit.log + type: FileOrCreate diff --git a/pkg/apiserver/apiserver.go b/pkg/apiserver/apiserver.go new file mode 100644 index 0000000..1b72d95 --- /dev/null +++ b/pkg/apiserver/apiserver.go @@ -0,0 +1,199 @@ +package apiserver + +import ( + "fmt" + "strings" + + "github.com/MatousJobanek/build-environment-detector/detector" + "github.com/MatousJobanek/build-environment-detector/detector/git" + "k8s.io/component-base/logs" + + "github.com/emicklei/go-restful" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/apimachinery/pkg/version" + genericapiserver "k8s.io/apiserver/pkg/server" + + utilruntime "k8s.io/apimachinery/pkg/util/runtime" +) + +const GroupName = "gitservice.devopsconsole.openshift.io" +const GroupVersion = "v1alpha1" + +var ( + Scheme = runtime.NewScheme() + Codecs = serializer.NewCodecFactory(Scheme) + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + AddToScheme = SchemeBuilder.AddToScheme + SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: GroupVersion} + + log = logs.NewLogger("git-api-server: ") +) + +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion) + return nil +} + +func init() { + utilruntime.Must(AddToScheme(Scheme)) + + // Setting VersionPriority is critical in the InstallAPIGroup call (done in New()) + utilruntime.Must(Scheme.SetVersionPriority(SchemeGroupVersion)) + metav1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: GroupVersion}) + + unversioned := schema.GroupVersion{Group: "", Version: GroupVersion} + Scheme.AddUnversionedTypes(unversioned, + &metav1.Status{}, + &metav1.APIVersions{}, + &metav1.APIGroupList{}, + &metav1.APIGroup{}, + &metav1.APIResourceList{}, + ) +} + +type ExtraConfig struct { + // Place you custom config here. +} + +type Config struct { + GenericConfig *genericapiserver.RecommendedConfig + ExtraConfig ExtraConfig +} + +// GitAPIServer contains state for a Kubernetes cluster master/api server. +type GitAPIServer struct { + GenericAPIServer *genericapiserver.GenericAPIServer +} + +type completedConfig struct { + GenericConfig genericapiserver.CompletedConfig + ExtraConfig *ExtraConfig +} + +type CompletedConfig struct { + // Embed a private pointer that cannot be instantiated outside of this package. + *completedConfig +} + +type GitSource struct { + Source string +} + +// Complete fills in any fields not set that are required to have valid data. It's mutating the receiver. +func (cfg *Config) Complete() CompletedConfig { + c := completedConfig{ + cfg.GenericConfig.Complete(), + &cfg.ExtraConfig, + } + + c.GenericConfig.Version = &version.Info{ + Major: "1", + Minor: "0", + } + + return CompletedConfig{&c} +} + +// New returns a new instance of GitAPIServer from the given config. +func (c completedConfig) New() (*GitAPIServer, error) { + genericServer, err := c.GenericConfig.New("DevOps Console Git API Server", genericapiserver.NewEmptyDelegate()) + if err != nil { + return nil, err + } + + s := &GitAPIServer{ + GenericAPIServer: genericServer, + } + + apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(GroupName, Scheme, metav1.ParameterCodec, Codecs) + + if err := s.GenericAPIServer.InstallAPIGroup(&apiGroupInfo); err != nil { + return nil, err + } + + installCompositionGitWebService(s) + + return s, nil +} + +func installCompositionGitWebService(gitServer *GitAPIServer) { + path := fmt.Sprintf("/apis/%s/%s/namespaces/{namespace}", GroupName, GroupVersion) + log.Println("WS PATH:" + path) + + ws := getWebService() + ws.Path(path). + Consumes(restful.MIME_JSON, restful.MIME_XML). + Produces(restful.MIME_JSON, restful.MIME_XML) + + testPath := "/{resource-id}/test" + log.Println("Test Path:" + testPath) + ws.Route(ws.GET(testPath).To(testResponse)) + + detectPath := "/detect" + log.Println("Detect Path:" + detectPath) + ws.Route(ws.POST(detectPath).To(detectResponse)) + + gitServer.GenericAPIServer.Handler.GoRestfulContainer.Add(ws) + log.Println("Done registering.") +} + +func getWebService() *restful.WebService { + ws := new(restful.WebService) + ws.Path("/apis") + ws.Consumes("*/*") + ws.Produces(restful.MIME_JSON, restful.MIME_XML) + ws.ApiVersion(GroupName) + return ws +} + +func testResponse(request *restful.Request, response *restful.Response) { + log.Println("Handling request...") + resourceName := request.PathParameter("resource-id") + requestPath := request.Request.URL.Path + resourcePathSlice := strings.Split(requestPath, "/") + resourceKind := resourcePathSlice[6] // Kind is 7th element in the slice + responseString := "Resource Name:" + resourceName + " Resource Kind: " + resourceKind + "\n" + response.Write([]byte(responseString)) +} + +func detectResponse(request *restful.Request, response *restful.Response) { + log.Println("Handling request...") + + gitSource := &GitSource{} + + err := request.ReadEntity(gitSource) + if err != nil { + response.Write([]byte((err.Error()))) + } + + log.Println("Detecting git source: " + gitSource.Source) + + src := &git.Source{ + URL: gitSource.Source, + Secret: git.NewUsernamePassword("anonymous", ""), + } + + buildEnvStats, err := detector.DetectBuildEnvironments(src) + if err != nil { + response.Write([]byte((err.Error()))) + } + + if buildEnvStats != nil { + for _, lang := range buildEnvStats.SortedLanguages { + response.Write([]byte("Language found: ")) + response.Write([]byte(lang)) + response.Write([]byte("\r\n")) + } + + for _, tool := range buildEnvStats.DetectedBuildTools { + response.Write([]byte("Build tool found: ")) + response.Write([]byte(fmt.Sprint(*tool))) + response.Write([]byte("\r\n")) + } + } else { + response.Write([]byte("No languages detected")) + } +} diff --git a/pkg/cmd/main.go b/pkg/cmd/main.go new file mode 100644 index 0000000..7b06ff9 --- /dev/null +++ b/pkg/cmd/main.go @@ -0,0 +1,25 @@ +package main + +import ( + "flag" + "os" + + server "github.com/redhat-developer/git-service/pkg/cmd/server" + genericapiserver "k8s.io/apiserver/pkg/server" + "k8s.io/component-base/logs" +) + +var log = logs.NewLogger("git-api-server: ") + +func main() { + logs.InitLogs() + defer logs.FlushLogs() + + stopCh := genericapiserver.SetupSignalHandler() + options := server.NewGitServerOptions(os.Stdout, os.Stderr) + cmd := server.NewCommandStartGitServer(options, stopCh) + cmd.Flags().AddGoFlagSet(flag.CommandLine) + if err := cmd.Execute(); err != nil { + log.Fatal(err) + } +} diff --git a/pkg/cmd/server/start.go b/pkg/cmd/server/start.go new file mode 100644 index 0000000..450efa1 --- /dev/null +++ b/pkg/cmd/server/start.go @@ -0,0 +1,100 @@ +package serverstrings + +import ( + "fmt" + "io" + "net" + + "github.com/spf13/cobra" + + "github.com/redhat-developer/git-service/pkg/apiserver" + utilerrors "k8s.io/apimachinery/pkg/util/errors" + genericapiserver "k8s.io/apiserver/pkg/server" + genericoptions "k8s.io/apiserver/pkg/server/options" +) + +const defaultEtcdPathPrefix = "/registry/gitservice.devopsconsole.openshift.io" + +type GitServerOptions struct { + RecommendedOptions *genericoptions.RecommendedOptions + StdOut io.Writer + StdErr io.Writer +} + +func NewGitServerOptions(out, errOut io.Writer) *GitServerOptions { + o := &GitServerOptions{ + RecommendedOptions: genericoptions.NewRecommendedOptions(defaultEtcdPathPrefix, + apiserver.Codecs.LegacyCodec(apiserver.SchemeGroupVersion), nil), + StdOut: out, + StdErr: errOut, + } + return o +} + +// NewCommandStartGitServer provides a CLI handler for 'start master' command +// with a default GitServerOptions. +func NewCommandStartGitServer(defaults *GitServerOptions, stopCh <-chan struct{}) *cobra.Command { + o := *defaults + cmd := &cobra.Command{ + Short: "Launch Git API server", + Long: "Launch Git API server", + RunE: func(c *cobra.Command, args []string) error { + if err := o.Complete(); err != nil { + return err + } + if err := o.Validate(args); err != nil { + return err + } + if err := o.RunGitServer(stopCh); err != nil { + return err + } + return nil + }, + } + + flags := cmd.Flags() + o.RecommendedOptions.AddFlags(flags) + + return cmd +} + +func (o GitServerOptions) Validate(args []string) error { + errors := []error{} + errors = append(errors, o.RecommendedOptions.Validate()...) + return utilerrors.NewAggregate(errors) +} + +func (o *GitServerOptions) Complete() error { + return nil +} + +func (o *GitServerOptions) Config() (*apiserver.Config, error) { + // TODO have a "real" external address + if err := o.RecommendedOptions.SecureServing.MaybeDefaultWithSelfSignedCerts("localhost", nil, []net.IP{net.ParseIP("127.0.0.1")}); err != nil { + return nil, fmt.Errorf("error creating self-signed certificates: %v", err) + } + + serverConfig := genericapiserver.NewRecommendedConfig(apiserver.Codecs) + if err := o.RecommendedOptions.ApplyTo(serverConfig); err != nil { + return nil, err + } + + config := &apiserver.Config{ + GenericConfig: serverConfig, + ExtraConfig: apiserver.ExtraConfig{}, + } + return config, nil +} + +func (o GitServerOptions) RunGitServer(stopCh <-chan struct{}) error { + config, err := o.Config() + if err != nil { + return err + } + + server, err := config.Complete().New() + if err != nil { + return err + } + return server.GenericAPIServer.PrepareRun().Run(stopCh) +}